• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package android.test;
18 
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;
26 
27 import junit.framework.Test;
28 import junit.framework.TestCase;
29 import junit.framework.TestSuite;
30 
31 import java.util.List;
32 
33 /**
34  * Tests for {@link InstrumentationTestRunner}
35  */
36 @SmallTest
37 public class InstrumentationTestRunnerTest extends TestCase {
38     private StubInstrumentationTestRunner mInstrumentationTestRunner;
39     private StubAndroidTestRunner mStubAndroidTestRunner;
40     private String mTargetContextPackageName;
41 
setUp()42     protected void setUp() throws Exception {
43         super.setUp();
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);
49     }
50 
testOverrideTestToRunWithClassArgument()51     public void testOverrideTestToRunWithClassArgument() throws Exception {
52         String expectedTestClassName = PlaceHolderTest.class.getName();
53         mInstrumentationTestRunner.onCreate(createBundle(
54                 InstrumentationTestRunner.ARGUMENT_TEST_CLASS, expectedTestClassName));
55 
56         assertTestRunnerCalledWithExpectedParameters(expectedTestClassName, "testPlaceHolder");
57     }
58 
testOverrideTestToRunWithClassAndMethodArgument()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));
65 
66         assertTestRunnerCalledWithExpectedParameters(expectedTestClassName,
67                 expectedTestMethodName);
68     }
69 
testUseSelfAsTestSuiteProviderWhenNoMetaDataOrClassArgument()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");
77     }
78 
testMultipleTestClass()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));
84 
85         Test test = mStubAndroidTestRunner.getTest();
86 
87         assertContentsInOrder(ListTestCaseNames.getTestNames((TestSuite) test),
88             new TestDescriptor(PlaceHolderTest.class.getName(), "testPlaceHolder"),
89             new TestDescriptor(PlaceHolderTest2.class.getName(), "testPlaceHolder2"));
90 
91     }
92 
93     /**
94      * Test that runtime exceptions during runTest are handled gracefully
95      */
testUnhandledException()96     public void testUnhandledException() throws Exception {
97         StubAndroidTestRunner stubAndroidTestRunner = new StubAndroidTestRunner() {
98             @Override
99             public void runTest() {
100                 throw new RuntimeException();
101             }
102         };
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"));
114     }
115 
116     /**
117      * Test that specifying a method which does not exist is handled gracefully
118      */
testBadMethodArgument()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,
126                 invalidMethodName);
127     }
128 
testDelayParameter()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(); } };
138 
139         // Should delay three times: before, between, and after the two tests.
140         long beforeTest = System.currentTimeMillis();
141         t.start();
142         t.join();
143         assertTrue(System.currentTimeMillis() > beforeTest + delayMsec * 3);
144         assertTrue(mInstrumentationTestRunner.isStarted());
145         assertTrue(mInstrumentationTestRunner.isFinished());
146         assertTrue(mStubAndroidTestRunner.isRun());
147     }
148 
149     /**
150      * Test that the -e {@link InstrumentationTestRunner.ARGUMENT_ANNOTATION} parameter properly
151      * selects tests.
152      */
testAnnotationParameter()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");
160     }
161 
162     /**
163      * Test that the -e {@link InstrumentationTestRunner.ARGUMENT_NOT_ANNOTATION} parameter
164      * properly excludes tests.
165      */
testNotAnnotationParameter()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");
174     }
175 
assertContentsInOrder(List<TestDescriptor> actual, TestDescriptor... source)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);
183         }
184     }
185 
assertTestRunnerCalledWithExpectedParameters( String expectedTestClassName, String expectedTestMethodName)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());
193     }
194 
createBundle(String key, String value)195     private Bundle createBundle(String key, String value) {
196         Bundle bundle = new Bundle();
197         bundle.putString(key, value);
198         return bundle;
199     }
200 
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;
211 
StubInstrumentationTestRunner(Context context, Context targetContext, AndroidTestRunner androidTestRunner)212         public StubInstrumentationTestRunner(Context context, Context targetContext,
213                 AndroidTestRunner androidTestRunner) {
214             this.mContext = context;
215             this.mTargetContext = targetContext;
216             this.mAndroidTestRunner = androidTestRunner;
217         }
218 
getContext()219         public Context getContext() {
220             return mContext;
221         }
222 
getAllTests()223         public TestSuite getAllTests() {
224             return mTestSuite;
225         }
226 
getTargetContext()227         public Context getTargetContext() {
228             return mTargetContext;
229         }
230 
getAndroidTestRunner()231         protected AndroidTestRunner getAndroidTestRunner() {
232             return mAndroidTestRunner;
233         }
234 
start()235         public void start() {
236             mStarted = true;
237         }
238 
finish(int resultCode, Bundle results)239         public void finish(int resultCode, Bundle results) {
240             mFinished = true;
241             mResults = results;
242         }
243 
isStarted()244         public boolean isStarted() {
245             return mStarted;
246         }
247 
isFinished()248         public boolean isFinished() {
249             return mFinished;
250         }
251 
setAllTestsSuite(TestSuite testSuite)252         public void setAllTestsSuite(TestSuite testSuite) {
253             mTestSuite = testSuite;
254         }
255 
setDefaultTestsSuite(TestSuite testSuite)256         public void setDefaultTestsSuite(TestSuite testSuite) {
257             mDefaultTestSuite = testSuite;
258         }
259 
getPackageNameForDefaultTests()260         public String getPackageNameForDefaultTests() {
261             return mPackageNameForDefaultTests;
262         }
263 
264         @Override
prepareLooper()265         void prepareLooper() {
266             // ignore
267         }
268     }
269 
270     private static class StubContext extends MockContext {
271         private String mPackageName;
272 
StubContext(String packageName)273         public StubContext(String packageName) {
274             this.mPackageName = packageName;
275         }
276 
277         @Override
getPackageCodePath()278         public String getPackageCodePath() {
279             return mPackageName;
280         }
281 
282         @Override
getPackageName()283         public String getPackageName() {
284             return mPackageName;
285         }
286 
287         @Override
getClassLoader()288         public ClassLoader getClassLoader() {
289             return getClass().getClassLoader();
290         }
291     }
292 
293     private static class StubAndroidTestRunner extends AndroidTestRunner {
294         private Test mTest;
295         private boolean mRun;
296 
isRun()297         public boolean isRun() {
298             return mRun;
299         }
300 
setTest(Test test)301         public void setTest(Test test) {
302             super.setTest(test);
303             mTest = test;
304         }
305 
getTest()306         public Test getTest() {
307             return mTest;
308         }
309 
runTest()310         public void runTest() {
311             super.runTest();
312             mRun = true;
313         }
314     }
315 
316     /**
317      * Empty test used for validation
318      */
319     public static class PlaceHolderTest extends TestCase {
320 
PlaceHolderTest()321         public PlaceHolderTest() {
322             super("testPlaceHolder");
323         }
324 
testPlaceHolder()325         public void testPlaceHolder() throws Exception {
326 
327         }
328     }
329 
330     /**
331      * Empty test used for validation
332      */
333     public static class PlaceHolderTest2 extends TestCase {
334 
PlaceHolderTest2()335         public PlaceHolderTest2() {
336             super("testPlaceHolder2");
337         }
338 
testPlaceHolder2()339         public void testPlaceHolder2() throws Exception {
340 
341         }
342     }
343 
344     /**
345      * Annotated test used for validation.
346      */
347     public static class AnnotationTest extends TestCase {
348 
testNotAnnotated()349         public void testNotAnnotated() throws Exception {
350         }
351 
352         @FlakyTest
testAnnotated()353         public void testAnnotated() throws Exception {
354         }
355     }
356 }
357