diff options
3 files changed, 50 insertions, 6 deletions
@@ -28,10 +28,19 @@ The `snippet` code can either be written in its own standalone apk, or as a of an existing apk. This allows you to write snippets that instrument or automate another app. -Under the hood, the snippet lib starts a web server which listens for requests -to trigger snippets. It locates the corrsponding methods by reflection, runs -them, and returns results over the tcp socket. All common built-in variable -types are supported as arguments. + +## Under The Hood + +A snippet is launched by an `am instrument` call. Snippets use a custom +`InstrumentationTestRunner` derived from `AndroidJUnitRunner`. This allows +for snippets that interact with a main app's classes, such as Espresso snippets, +and allows you to get either the test app's or the main app's context from +`InstrumentationRegistry`. + +Once started, the special runner starts a web server which listens for requests +to trigger snippets. The server's handler locates the corrsponding methods by +reflection, runs them, and returns results over the tcp socket. All common +built-in variable types are supported as arguments. ## Usage diff --git a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/SnippetRunner.java b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/SnippetRunner.java index 6bfa87c..aa51009 100644 --- a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/SnippetRunner.java +++ b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/SnippetRunner.java @@ -23,6 +23,7 @@ import android.os.Process; import android.support.test.runner.AndroidJUnitRunner; import com.google.android.mobly.snippet.rpc.AndroidProxy; +import com.google.android.mobly.snippet.util.EmptyTestClass; import com.google.android.mobly.snippet.util.Log; import com.google.android.mobly.snippet.util.NotificationIdFactory; import java.io.IOException; @@ -32,7 +33,10 @@ import java.net.SocketException; * A launcher that starts the snippet server as an instrumentation so that it has access to the * target app's context. * - * It is written this way to be compatible with 'am instrument'. + * <p>We have to extend some subclass of {@link android.test.InstrumentationTestRunner} because + * snippets are launched with 'am instrument'. We're specifically extending + * {@link AndroidJUnitRunner} because Espresso requires being called through it, since it sets up + * {@link android.support.test.InstrumentationRegistry} which Espresso requires. */ public class SnippetRunner extends AndroidJUnitRunner { private static final String ARG_ACTION = "action"; @@ -49,9 +53,12 @@ public class SnippetRunner extends AndroidJUnitRunner { @Override public void onCreate(Bundle arguments) { mArguments = arguments; + // Prevent this runner from triggering any real JUnit tests in the snippet by feeding it a + // hardcoded empty test class. + mArguments.putString("class", EmptyTestClass.class.getCanonicalName()); mNotificationManager = (NotificationManager) getTargetContext().getSystemService(Context.NOTIFICATION_SERVICE); - super.onCreate(arguments); + super.onCreate(mArguments); } @Override diff --git a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/util/EmptyTestClass.java b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/util/EmptyTestClass.java new file mode 100644 index 0000000..ac1920f --- /dev/null +++ b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/util/EmptyTestClass.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.android.mobly.snippet.util; + +import org.junit.Ignore; + +/** + * A stub JUnit class with no tests. + * + * <p>Used for 'safely' calling AndroidJUnitRunner methods on snippets that happen to have tests + * defined, to avoid actually calling those tests. + */ +@Ignore +public class EmptyTestClass {} |