2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 import android.app.Instrumentation;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.test.mock.MockContext;
23 import android.test.suitebuilder.ListTestCaseNames;
24 import android.test.suitebuilder.ListTestCaseNames.TestDescriptor;
25 import android.test.suitebuilder.annotation.SmallTest;
27 import junit.framework.Test;
28 import junit.framework.TestCase;
29 import junit.framework.TestSuite;
31 import java.util.List;
34 * Tests for {@link InstrumentationTestRunner}
37 public class InstrumentationTestRunnerTest extends TestCase {
38 private StubInstrumentationTestRunner mInstrumentationTestRunner;
39 private StubAndroidTestRunner mStubAndroidTestRunner;
40 private String mTargetContextPackageName;
42 protected void setUp() throws Exception {
44 mStubAndroidTestRunner = new StubAndroidTestRunner();
45 mTargetContextPackageName = "android.test.suitebuilder.examples";
46 mInstrumentationTestRunner = new StubInstrumentationTestRunner(
47 new StubContext("com.google.foo.tests"),
48 new StubContext(mTargetContextPackageName), mStubAndroidTestRunner);
51 public void testOverrideTestToRunWithClassArgument() throws Exception {
52 String expectedTestClassName = PlaceHolderTest.class.getName();
53 mInstrumentationTestRunner.onCreate(createBundle(
54 InstrumentationTestRunner.ARGUMENT_TEST_CLASS, expectedTestClassName));
56 assertTestRunnerCalledWithExpectedParameters(expectedTestClassName, "testPlaceHolder");
59 public void testOverrideTestToRunWithClassAndMethodArgument() throws Exception {
60 String expectedTestClassName = PlaceHolderTest.class.getName();
61 String expectedTestMethodName = "testPlaceHolder";
62 String classAndMethod = expectedTestClassName + "#" + expectedTestMethodName;
63 mInstrumentationTestRunner.onCreate(createBundle(
64 InstrumentationTestRunner.ARGUMENT_TEST_CLASS, classAndMethod));
66 assertTestRunnerCalledWithExpectedParameters(expectedTestClassName,
67 expectedTestMethodName);
70 public void testUseSelfAsTestSuiteProviderWhenNoMetaDataOrClassArgument() throws Exception {
71 TestSuite testSuite = new TestSuite();
72 testSuite.addTestSuite(PlaceHolderTest.class);
73 mInstrumentationTestRunner.setAllTestsSuite(testSuite);
74 mInstrumentationTestRunner.onCreate(null);
75 assertTestRunnerCalledWithExpectedParameters(
76 PlaceHolderTest.class.getName(), "testPlaceHolder");
79 public void testMultipleTestClass() throws Exception {
80 String classArg = PlaceHolderTest.class.getName() + "," +
81 PlaceHolderTest2.class.getName();
82 mInstrumentationTestRunner.onCreate(createBundle(
83 InstrumentationTestRunner.ARGUMENT_TEST_CLASS, classArg));
85 Test test = mStubAndroidTestRunner.getTest();
87 assertContentsInOrder(ListTestCaseNames.getTestNames((TestSuite) test),
88 new TestDescriptor(PlaceHolderTest.class.getName(), "testPlaceHolder"),
89 new TestDescriptor(PlaceHolderTest2.class.getName(), "testPlaceHolder2"));
94 * Test that runtime exceptions during runTest are handled gracefully
96 public void testUnhandledException() throws Exception {
97 StubAndroidTestRunner stubAndroidTestRunner = new StubAndroidTestRunner() {
99 public void runTest() {
100 throw new RuntimeException();
103 StubInstrumentationTestRunner instrumentationTestRunner = new StubInstrumentationTestRunner(
104 new StubContext("com.google.foo.tests"),
105 new StubContext(mTargetContextPackageName), stubAndroidTestRunner);
106 instrumentationTestRunner.onCreate(new Bundle());
107 instrumentationTestRunner.onStart();
108 assertTrue("Instrumentation did not finish", instrumentationTestRunner.isFinished());
109 // ensure a meaningful error message placed in results
110 String resultsData = instrumentationTestRunner.mResults.getString(
111 Instrumentation.REPORT_KEY_STREAMRESULT);
112 assertTrue("Instrumentation results is missing RuntimeException",
113 resultsData.contains("RuntimeException"));
117 * Test that specifying a method which does not exist is handled gracefully
119 public void testBadMethodArgument() throws Exception {
120 String testClassName = PlaceHolderTest.class.getName();
121 String invalidMethodName = "testNoExist";
122 String classAndMethod = testClassName + "#" + invalidMethodName;
123 mInstrumentationTestRunner.onCreate(createBundle(
124 InstrumentationTestRunner.ARGUMENT_TEST_CLASS, classAndMethod));
125 assertTestRunnerCalledWithExpectedParameters(testClassName,
129 public void testDelayParameter() throws Exception {
130 int delayMsec = 1000;
131 Bundle args = new Bundle();
132 args.putInt(InstrumentationTestRunner.ARGUMENT_DELAY_MSEC, delayMsec);
133 args.putString(InstrumentationTestRunner.ARGUMENT_TEST_CLASS,
134 PlaceHolderTest.class.getName() + "," +
135 PlaceHolderTest2.class.getName());
136 mInstrumentationTestRunner.onCreate(args);
137 Thread t = new Thread() { public void run() { mInstrumentationTestRunner.onStart(); } };
139 // Should delay three times: before, between, and after the two tests.
140 long beforeTest = System.currentTimeMillis();
143 assertTrue(System.currentTimeMillis() > beforeTest + delayMsec * 3);
144 assertTrue(mInstrumentationTestRunner.isStarted());
145 assertTrue(mInstrumentationTestRunner.isFinished());
146 assertTrue(mStubAndroidTestRunner.isRun());
150 * Test that the -e {@link InstrumentationTestRunner.ARGUMENT_ANNOTATION} parameter properly
153 public void testAnnotationParameter() throws Exception {
154 String expectedTestClassName = AnnotationTest.class.getName();
155 Bundle args = new Bundle();
156 args.putString(InstrumentationTestRunner.ARGUMENT_TEST_CLASS, expectedTestClassName);
157 args.putString(InstrumentationTestRunner.ARGUMENT_ANNOTATION, FlakyTest.class.getName());
158 mInstrumentationTestRunner.onCreate(args);
159 assertTestRunnerCalledWithExpectedParameters(expectedTestClassName, "testAnnotated");
163 * Test that the -e {@link InstrumentationTestRunner.ARGUMENT_NOT_ANNOTATION} parameter
164 * properly excludes tests.
166 public void testNotAnnotationParameter() throws Exception {
167 String expectedTestClassName = AnnotationTest.class.getName();
168 Bundle args = new Bundle();
169 args.putString(InstrumentationTestRunner.ARGUMENT_TEST_CLASS, expectedTestClassName);
170 args.putString(InstrumentationTestRunner.ARGUMENT_NOT_ANNOTATION,
171 FlakyTest.class.getName());
172 mInstrumentationTestRunner.onCreate(args);
173 assertTestRunnerCalledWithExpectedParameters(expectedTestClassName, "testNotAnnotated");
176 private void assertContentsInOrder(List<TestDescriptor> actual, TestDescriptor... source) {
177 TestDescriptor[] clonedSource = source.clone();
178 assertEquals("Unexpected number of items.", clonedSource.length, actual.size());
179 for (int i = 0; i < actual.size(); i++) {
180 TestDescriptor actualItem = actual.get(i);
181 TestDescriptor sourceItem = clonedSource[i];
182 assertEquals("Unexpected item. Index: " + i, sourceItem, actualItem);
186 private void assertTestRunnerCalledWithExpectedParameters(
187 String expectedTestClassName, String expectedTestMethodName) {
188 Test test = mStubAndroidTestRunner.getTest();
189 assertContentsInOrder(ListTestCaseNames.getTestNames((TestSuite) test),
190 new TestDescriptor(expectedTestClassName, expectedTestMethodName));
191 assertTrue(mInstrumentationTestRunner.isStarted());
192 assertFalse(mInstrumentationTestRunner.isFinished());
195 private Bundle createBundle(String key, String value) {
196 Bundle bundle = new Bundle();
197 bundle.putString(key, value);
201 private static class StubInstrumentationTestRunner extends InstrumentationTestRunner {
202 private Context mContext;
203 private Context mTargetContext;
204 private boolean mStarted;
205 private boolean mFinished;
206 private AndroidTestRunner mAndroidTestRunner;
207 private TestSuite mTestSuite;
208 private TestSuite mDefaultTestSuite;
209 private String mPackageNameForDefaultTests;
210 private Bundle mResults;
212 public StubInstrumentationTestRunner(Context context, Context targetContext,
213 AndroidTestRunner androidTestRunner) {
214 this.mContext = context;
215 this.mTargetContext = targetContext;
216 this.mAndroidTestRunner = androidTestRunner;
219 public Context getContext() {
223 public TestSuite getAllTests() {
227 public Context getTargetContext() {
228 return mTargetContext;
231 protected AndroidTestRunner getAndroidTestRunner() {
232 return mAndroidTestRunner;
235 public void start() {
239 public void finish(int resultCode, Bundle results) {
244 public boolean isStarted() {
248 public boolean isFinished() {
252 public void setAllTestsSuite(TestSuite testSuite) {
253 mTestSuite = testSuite;
256 public void setDefaultTestsSuite(TestSuite testSuite) {
257 mDefaultTestSuite = testSuite;
260 public String getPackageNameForDefaultTests() {
261 return mPackageNameForDefaultTests;
265 void prepareLooper() {
270 private static class StubContext extends MockContext {
271 private String mPackageName;
273 public StubContext(String packageName) {
274 this.mPackageName = packageName;
278 public String getPackageCodePath() {
283 public String getPackageName() {
288 public ClassLoader getClassLoader() {
289 return getClass().getClassLoader();
293 private static class StubAndroidTestRunner extends AndroidTestRunner {
295 private boolean mRun;
297 public boolean isRun() {
301 public void setTest(Test test) {
306 public Test getTest() {
310 public void runTest() {
317 * Empty test used for validation
319 public static class PlaceHolderTest extends TestCase {
321 public PlaceHolderTest() {
322 super("testPlaceHolder");
325 public void testPlaceHolder() throws Exception {
331 * Empty test used for validation
333 public static class PlaceHolderTest2 extends TestCase {
335 public PlaceHolderTest2() {
336 super("testPlaceHolder2");
339 public void testPlaceHolder2() throws Exception {
345 * Annotated test used for validation.
347 public static class AnnotationTest extends TestCase {
349 public void testNotAnnotated() throws Exception {
353 public void testAnnotated() throws Exception {