Add InjectBundle annotation for JUnit4 tests.
This allows tests to receive arguments passed in on the command line.
A future commit will add similar functionality to JUnit3 tests.
DO NOT MERGE
Change-Id: I57fa52b73b8faf1179212778eb82c67ec5eed7b0
diff --git a/androidtestlib/src/com/android/test/InjectBundle.java b/androidtestlib/src/com/android/test/InjectBundle.java
new file mode 100644
index 0000000..f3c2399
--- /dev/null
+++ b/androidtestlib/src/com/android/test/InjectBundle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.android.test;
+
+import android.os.Bundle;
+
+import junit.framework.Test;
+
+import org.junit.Before;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this to inject a {@link Bundle} containing the command line arguments passed to the
+ * test runner into your JUnit4-style test.
+ * <p/>
+ * To use, just add the correct annotation to an {@link Bundle} field like this:
+ * <pre>
+ * @InjectBundle public Bundle mMyBundle;
+ * </pre>
+ * The test runner will set the value of this field with the {@link Bundle} after
+ * object construction but before any {@link Before} methods are called.
+ * <p/>
+ * Declaring this in a JUnit3 test (ie a class that is a {@link Test}) will have no effect.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface InjectBundle {
+
+}
diff --git a/androidtestlib/src/com/android/test/runner/AndroidJUnitRunner.java b/androidtestlib/src/com/android/test/runner/AndroidJUnitRunner.java
index a932523..d3bf6bd 100644
--- a/androidtestlib/src/com/android/test/runner/AndroidJUnitRunner.java
+++ b/androidtestlib/src/com/android/test/runner/AndroidJUnitRunner.java
@@ -305,7 +305,7 @@
if (getBooleanArgument(ARGUMENT_LOG_ONLY)) {
builder.setSkipExecution(true);
}
- return builder.build(this);
+ return builder.build(this, arguments);
}
/**
diff --git a/androidtestlib/src/com/android/test/runner/AndroidRunnerBuilder.java b/androidtestlib/src/com/android/test/runner/AndroidRunnerBuilder.java
index d56861a..328d413 100644
--- a/androidtestlib/src/com/android/test/runner/AndroidRunnerBuilder.java
+++ b/androidtestlib/src/com/android/test/runner/AndroidRunnerBuilder.java
@@ -16,6 +16,7 @@
package com.android.test.runner;
import android.app.Instrumentation;
+import android.os.Bundle;
import com.android.test.runner.junit3.AndroidJUnit3Builder;
import com.android.test.runner.junit4.AndroidJUnit4Builder;
@@ -29,16 +30,14 @@
*/
class AndroidRunnerBuilder extends AllDefaultPossibilitiesBuilder {
- private final Instrumentation mInstr;
private final AndroidJUnit3Builder mAndroidJUnit3Builder;
private final AndroidJUnit4Builder mAndroidJUnit4Builder;
- public AndroidRunnerBuilder(boolean canUseSuiteMethod, Instrumentation instr,
+ public AndroidRunnerBuilder(boolean canUseSuiteMethod, Instrumentation instr, Bundle bundle,
boolean skipExecution) {
super(canUseSuiteMethod);
- mInstr = instr;
- mAndroidJUnit3Builder = new AndroidJUnit3Builder(mInstr, skipExecution);
- mAndroidJUnit4Builder = new AndroidJUnit4Builder(mInstr, skipExecution);
+ mAndroidJUnit3Builder = new AndroidJUnit3Builder(instr, skipExecution);
+ mAndroidJUnit4Builder = new AndroidJUnit4Builder(instr, bundle, skipExecution);
}
@Override
diff --git a/androidtestlib/src/com/android/test/runner/TestRequestBuilder.java b/androidtestlib/src/com/android/test/runner/TestRequestBuilder.java
index a15b70e..7077517 100644
--- a/androidtestlib/src/com/android/test/runner/TestRequestBuilder.java
+++ b/androidtestlib/src/com/android/test/runner/TestRequestBuilder.java
@@ -16,6 +16,7 @@
package com.android.test.runner;
import android.app.Instrumentation;
+import android.os.Bundle;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -207,13 +208,13 @@
* If no classes have been explicitly added, will scan the classpath for all tests.
*
*/
- public TestRequest build(Instrumentation instr) {
+ public TestRequest build(Instrumentation instr, Bundle bundle) {
if (mTestLoader.isEmpty()) {
// no class restrictions have been specified. Load all classes
loadClassesFromClassPath();
}
- Request request = classes(instr, mSkipExecution, new Computer(),
+ Request request = classes(instr, bundle, mSkipExecution, new Computer(),
mTestLoader.getLoadedClasses().toArray(new Class[0]));
return new TestRequest(mTestLoader.getLoadFailures(), request.filterWith(mFilter));
}
@@ -223,14 +224,17 @@
* in a set of classes.
*
* @param instr the {@link Instrumentation} to inject into any tests that require it
+ * @param bundle the {@link Bundle} of command line args to inject into any tests that require
+ * it
* @param computer Helps construct Runners from classes
* @param classes the classes containing the tests
* @return a <code>Request</code> that will cause all tests in the classes to be run
*/
- private static Request classes(Instrumentation instr, boolean skipExecution,
+ private static Request classes(Instrumentation instr, Bundle bundle, boolean skipExecution,
Computer computer, Class<?>... classes) {
try {
- AndroidRunnerBuilder builder = new AndroidRunnerBuilder(true, instr, skipExecution);
+ AndroidRunnerBuilder builder = new AndroidRunnerBuilder(true, instr, bundle,
+ skipExecution);
Runner suite = computer.getSuite(builder, classes);
return Request.runner(suite);
} catch (InitializationError e) {
diff --git a/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4Builder.java b/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4Builder.java
index 1b14a9a..6a08b6a 100644
--- a/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4Builder.java
+++ b/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4Builder.java
@@ -16,6 +16,7 @@
package com.android.test.runner.junit4;
import android.app.Instrumentation;
+import android.os.Bundle;
import com.android.test.InjectContext;
import com.android.test.InjectInstrumentation;
@@ -32,10 +33,12 @@
public class AndroidJUnit4Builder extends RunnerBuilder {
private final Instrumentation mInstrumentation;
+ private final Bundle mBundle;
private boolean mSkipExecution;
- public AndroidJUnit4Builder(Instrumentation instr, boolean skipExecution) {
+ public AndroidJUnit4Builder(Instrumentation instr, Bundle bundle, boolean skipExecution) {
mInstrumentation = instr;
+ mBundle = bundle;
mSkipExecution = skipExecution;
}
@@ -45,7 +48,7 @@
return new NonExecutingJUnit4ClassRunner(testClass);
}
if (hasInjectedFields(testClass)) {
- return new AndroidJUnit4ClassRunner(testClass, mInstrumentation);
+ return new AndroidJUnit4ClassRunner(testClass, mInstrumentation, mBundle);
}
return null;
}
diff --git a/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4ClassRunner.java b/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4ClassRunner.java
index 41d5ad4..4b6e00c 100644
--- a/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4ClassRunner.java
+++ b/androidtestlib/src/com/android/test/runner/junit4/AndroidJUnit4ClassRunner.java
@@ -17,8 +17,10 @@
import android.app.Instrumentation;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
+import com.android.test.InjectBundle;
import com.android.test.InjectContext;
import com.android.test.InjectInstrumentation;
@@ -37,6 +39,7 @@
private static final String LOG_TAG = "AndroidJUnit4ClassRunner";
private final Instrumentation mInstr;
+ private final Bundle mBundle;
@SuppressWarnings("serial")
private static class InvalidInjectException extends Exception {
@@ -45,10 +48,11 @@
}
}
- public AndroidJUnit4ClassRunner(Class<?> klass, Instrumentation instr)
+ public AndroidJUnit4ClassRunner(Class<?> klass, Instrumentation instr, Bundle bundle)
throws InitializationError {
super(klass);
mInstr = instr;
+ mBundle = bundle;
}
@Override
@@ -76,6 +80,11 @@
for (FrameworkField contextField : contextFields) {
validateInjectField(errors, contextField, Context.class);
}
+ List<FrameworkField> bundleFields = getTestClass().getAnnotatedFields(
+ InjectBundle.class);
+ for (FrameworkField bundleField : bundleFields) {
+ validateInjectField(errors, bundleField, Context.class);
+ }
}
private void validateInjectField(List<Throwable> errors, FrameworkField instrField,
@@ -104,6 +113,11 @@
for (FrameworkField contextField : contextFields) {
setFieldValue(test, contextField.getField(), mInstr.getTargetContext());
}
+ List<FrameworkField> bundleFields = getTestClass().getAnnotatedFields(
+ InjectBundle.class);
+ for (FrameworkField bundleField : bundleFields) {
+ setFieldValue(test, bundleField.getField(), mBundle);
+ }
}
private void setFieldValue(Object test, Field field, Object value) {
diff --git a/androidtestlib/tests/src/com/android/test/runner/TestRequestBuilderTest.java b/androidtestlib/tests/src/com/android/test/runner/TestRequestBuilderTest.java
index 4d7d9bb..9c4ae12 100644
--- a/androidtestlib/tests/src/com/android/test/runner/TestRequestBuilderTest.java
+++ b/androidtestlib/tests/src/com/android/test/runner/TestRequestBuilderTest.java
@@ -16,8 +16,10 @@
package com.android.test.runner;
import android.app.Instrumentation;
+import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.test.InjectBundle;
import com.android.test.InjectInstrumentation;
import org.junit.Assert;
@@ -60,6 +62,10 @@
@InjectInstrumentation
public Instrumentation mInstr;
+ @InjectBundle
+ public Bundle mBundle;
+
+
/**
* Test initial condition for size filtering - that all tests run when no filter is attached
*/
@@ -67,7 +73,7 @@
public void testNoSize() {
TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream()));
b.addTestClass(SampleTest.class.getName());
- TestRequest request = b.build(mInstr);
+ TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(2, result.getRunCount());
@@ -81,7 +87,7 @@
TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream()));
b.addTestClass(SampleTest.class.getName());
b.addTestSizeFilter("small");
- TestRequest request = b.build(mInstr);
+ TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(1, result.getRunCount());
@@ -96,7 +102,7 @@
b.addTestClass(SampleTest.class.getName());
b.addTestClass(SampleClassSize.class.getName());
b.addTestSizeFilter("small");
- TestRequest request = b.build(mInstr);
+ TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(3, result.getRunCount());
@@ -111,7 +117,7 @@
b.addAnnotationInclusionFilter(SmallTest.class.getName());
b.addTestClass(SampleTest.class.getName());
b.addTestClass(SampleClassSize.class.getName());
- TestRequest request = b.build(mInstr);
+ TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(3, result.getRunCount());
@@ -126,7 +132,7 @@
b.addAnnotationExclusionFilter(SmallTest.class.getName());
b.addTestClass(SampleTest.class.getName());
b.addTestClass(SampleClassSize.class.getName());
- TestRequest request = b.build(mInstr);
+ TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(1, result.getRunCount());