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