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
17package android.test;
18
19import android.test.mock.MockContext;
20import android.test.suitebuilder.annotation.SmallTest;
21
22import java.util.ArrayList;
23import junit.framework.TestCase;
24import junit.framework.AssertionFailedError;
25import junit.framework.Test;
26import junit.framework.TestSuite;
27import junit.framework.TestListener;
28
29import java.util.List;
30import java.util.Arrays;
31
32/**
33 * Unit tests for {@link AndroidTestRunner}
34 */
35@SmallTest
36public class AndroidTestRunnerTest extends TestCase {
37    private AndroidTestRunner mAndroidTestRunner;
38    private StubContext mStubContext;
39
40    @Override
41    protected void setUp() throws Exception {
42        super.setUp();
43        mStubContext = new StubContext(getClass().getClassLoader());
44
45        mAndroidTestRunner = new AndroidTestRunner();
46        mAndroidTestRunner.setContext(mStubContext);
47    }
48
49    public void testLoadNoTestCases() throws Exception {
50        mAndroidTestRunner.setTestClassName(TestSuite.class.getName(), null);
51
52        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
53        assertNotNull(testCases);
54        assertEquals(1, testCases.size());
55        assertEquals("warning", testCases.get(0).getName());
56        assertEquals(TestSuite.class.getSimpleName(), mAndroidTestRunner.getTestClassName());
57    }
58
59    public void testSetTestSuiteWithOneTestCase() throws Exception {
60        mAndroidTestRunner.setTestClassName(OneTestTestCase.class.getName(), null);
61
62        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
63        assertNotNull(testCases);
64        assertEquals(1, testCases.size());
65        assertEquals("testOne", testCases.get(0).getName());
66        assertEquals(OneTestTestCase.class.getSimpleName(), mAndroidTestRunner.getTestClassName());
67    }
68
69    public void testRunTest() throws Exception {
70        mAndroidTestRunner.setTestClassName(OneTestTestCase.class.getName(), null);
71
72        TestListenerStub testListenerStub = new TestListenerStub();
73        mAndroidTestRunner.addTestListener(testListenerStub);
74
75        mAndroidTestRunner.runTest();
76
77        assertTrue(testListenerStub.saw("testOne"));
78    }
79
80    public void testRunTestWithAndroidTestCase() throws Exception {
81        mAndroidTestRunner.setTestClassName(
82                OneAndroidTestTestCase.class.getName(), "testOneAndroid");
83
84        TestListenerStub testListenerStub = new TestListenerStub();
85        mAndroidTestRunner.addTestListener(testListenerStub);
86
87        assertNull(((AndroidTestCase) mAndroidTestRunner.getTestCases().get(0)).getContext());
88
89        mAndroidTestRunner.runTest();
90
91        assertTrue(testListenerStub.saw("testOneAndroid"));
92        assertSame(mStubContext,
93                ((AndroidTestCase) mAndroidTestRunner.getTestCases().get(0)).getContext());
94    }
95
96    public void testRunTestWithAndroidTestCaseInSuite() throws Exception {
97        mAndroidTestRunner.setTestClassName(OneAndroidTestTestCase.class.getName(), null);
98
99        TestListenerStub testListenerStub = new TestListenerStub();
100        mAndroidTestRunner.addTestListener(testListenerStub);
101
102        mAndroidTestRunner.runTest();
103
104        assertTrue(testListenerStub.saw("testOneAndroid"));
105
106        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
107        for (TestCase testCase : testCases) {
108            assertSame(mStubContext, ((AndroidTestCase) testCase).getContext());
109        }
110    }
111
112    public void testRunTestWithAndroidTestCaseInNestedSuite() throws Exception {
113        mAndroidTestRunner.setTestClassName(AndroidTestCaseTestSuite.class.getName(), null);
114
115        TestListenerStub testListenerStub = new TestListenerStub();
116        mAndroidTestRunner.addTestListener(testListenerStub);
117
118        mAndroidTestRunner.runTest();
119
120        assertTrue(testListenerStub.saw("testOneAndroid"));
121
122        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
123        for (TestCase testCase : testCases) {
124            assertSame(mStubContext, ((AndroidTestCase) testCase).getContext());
125        }
126    }
127
128    public void testRunTestWithNullListener() throws Exception {
129        mAndroidTestRunner.setTestClassName(OneTestTestCase.class.getName(), null);
130
131        mAndroidTestRunner.addTestListener(null);
132        try {
133            mAndroidTestRunner.runTest();
134        } catch (NullPointerException e) {
135            fail("Should not add a null TestListener");
136        }
137    }
138
139    public void testSetTestClassWithTestSuiteProvider() throws Exception {
140        mAndroidTestRunner.setTestClassName(SampleTestSuiteProvider.class.getName(), null);
141        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
142        List<String> testNames = new ArrayList<>();
143        for (TestCase testCase : testCases) {
144            testNames.add(testCase.getName());
145        }
146
147        // Use the test suite provided by the interface method rather than the static suite method.
148        assertEquals(Arrays.asList("testOne"), testNames);
149    }
150
151    public void testSetTestClassWithTestSuite() throws Exception {
152        mAndroidTestRunner.setTestClassName(SampleTestSuite.class.getName(), null);
153        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
154        List<String> testNames = new ArrayList<>();
155        for (TestCase testCase : testCases) {
156            testNames.add(testCase.getName());
157        }
158        assertEquals(Arrays.asList("testOne", "testOne", "testTwo"), testNames);
159    }
160
161    public void testRunSingleTestMethod() throws Exception {
162        String testMethodName = "testTwo";
163        mAndroidTestRunner.setTestClassName(TwoTestTestCase.class.getName(), testMethodName);
164        List<TestCase> testCases = mAndroidTestRunner.getTestCases();
165        List<String> testNames = new ArrayList<>();
166        for (TestCase testCase : testCases) {
167            testNames.add(testCase.getName());
168        }
169        assertEquals(Arrays.asList(testMethodName), testNames);
170    }
171
172    public void testSetTestClassInvalidClass() throws Exception {
173        try {
174            mAndroidTestRunner.setTestClassName("class.that.does.not.exist", null);
175            fail("expected exception not thrown");
176        } catch (RuntimeException e) {
177            // expected
178        }
179    }
180
181    public void testRunSkipExecution() throws Exception {
182        String testMethodName = "testFail";
183        mAndroidTestRunner.setTestClassName(
184                OnePassOneErrorOneFailTestCase.class.getName(), testMethodName);
185
186        TestListenerStub testListenerStub = new TestListenerStub();
187        mAndroidTestRunner.addTestListener(testListenerStub);
188
189        // running the failing test should pass - ie as if its not run
190        mAndroidTestRunner.runTest();
191
192        assertTrue(testListenerStub.saw("testFail"));
193    }
194
195    public static class SampleTestSuiteProvider implements TestSuiteProvider {
196
197        public TestSuite getTestSuite() {
198            TestSuite testSuite = new TestSuite();
199            testSuite.addTestSuite(OneTestTestCase.class);
200            return testSuite;
201        }
202
203        public static Test suite() {
204            return SampleTestSuite.suite();
205        }
206    }
207
208    public static class SampleTestSuite {
209        public static TestSuite suite() {
210            TestSuite testSuite = new TestSuite();
211            testSuite.addTestSuite(OneTestTestCase.class);
212            testSuite.addTestSuite(TwoTestTestCase.class);
213            return testSuite;
214        }
215    }
216
217    public static class AndroidTestCaseTestSuite {
218        public static TestSuite suite() {
219            TestSuite testSuite = new TestSuite();
220            testSuite.addTestSuite(OneAndroidTestTestCase.class);
221            return testSuite;
222        }
223    }
224
225    public static class OneAndroidTestTestCase extends AndroidTestCase {
226        public void testOneAndroid() throws Exception {
227        }
228    }
229
230    public static class OneTestTestCase extends TestCase {
231        public void testOne() throws Exception {
232        }
233    }
234
235    public static class TwoTestTestCase extends TestCase {
236        public void testOne() throws Exception {
237        }
238
239        public void testTwo() throws Exception {
240        }
241    }
242
243    public static class OnePassOneErrorOneFailTestCase extends TestCase {
244        public void testPass() throws Exception {
245        }
246
247        public void testError() throws Exception {
248            throw new Exception();
249        }
250
251        public void testFail() throws Exception {
252            fail();
253        }
254    }
255
256    private static class TestListenerStub implements TestListener {
257        List<String> testNames = new ArrayList<>();
258
259        public void addError(Test test, Throwable t) {
260        }
261
262        public void addFailure(Test test, AssertionFailedError t) {
263        }
264
265        public void endTest(Test test) {
266        }
267
268        public void startTest(Test test) {
269            if (test instanceof TestCase) {
270                testNames.add(((TestCase) test).getName());
271            } else if (test instanceof TestSuite) {
272                testNames.add(((TestSuite) test).getName());
273            }
274        }
275
276        public boolean saw(String testName) {
277            return testNames.contains(testName);
278        }
279    }
280
281    private static class StubContext extends MockContext {
282        private ClassLoader mClassLoader;
283
284        public StubContext(ClassLoader classLoader) {
285            this.mClassLoader = classLoader;
286        }
287
288        @Override
289        public ClassLoader getClassLoader() {
290            return mClassLoader;
291        }
292    }
293}
294