blob: 79cedb009e8a8e1b760ec930a25807970e346465 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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.app.Instrumentation;
20import android.content.Context;
21import com.google.android.collect.Lists;
22import junit.framework.Test;
23import junit.framework.TestCase;
24import junit.framework.TestListener;
25import junit.framework.TestResult;
26import junit.framework.TestSuite;
27import junit.runner.BaseTestRunner;
28
29import java.lang.reflect.InvocationTargetException;
30import java.util.List;
31
32public class AndroidTestRunner extends BaseTestRunner {
33
34 private TestResult mTestResult;
35 private String mTestClassName;
36 private List<TestCase> mTestCases;
37 private Context mContext;
38 private boolean mSkipExecution = false;
39
40 private List<TestListener> mTestListeners = Lists.newArrayList();
41 private Instrumentation mInstrumentation;
42
43 @SuppressWarnings("unchecked")
44 public void setTestClassName(String testClassName, String testMethodName) {
45 Class testClass = loadTestClass(testClassName);
46
47 if (shouldRunSingleTestMethod(testMethodName, testClass)) {
48 TestCase testCase = buildSingleTestMethod(testClass, testMethodName);
49 mTestCases = Lists.newArrayList(testCase);
50 mTestClassName = testClass.getSimpleName();
51 } else {
52 setTest(getTest(testClass), testClass);
53 }
54 }
55
56 public void setTest(Test test) {
57 setTest(test, test.getClass());
58 }
59
60 private void setTest(Test test, Class<? extends Test> testClass) {
61 mTestCases = (List<TestCase>) TestCaseUtil.getTests(test, true);
62 if (TestSuite.class.isAssignableFrom(testClass)) {
63 mTestClassName = TestCaseUtil.getTestName(test);
64 } else {
65 mTestClassName = testClass.getSimpleName();
66 }
67 }
68
69 public void clearTestListeners() {
70 mTestListeners.clear();
71 }
72
73 public void addTestListener(TestListener testListener) {
74 if (testListener != null) {
75 mTestListeners.add(testListener);
76 }
77 }
78
79 @SuppressWarnings("unchecked")
80 private Class<? extends Test> loadTestClass(String testClassName) {
81 try {
82 return (Class<? extends Test>) mContext.getClassLoader().loadClass(testClassName);
83 } catch (ClassNotFoundException e) {
84 runFailed("Could not find test class. Class: " + testClassName);
85 }
86 return null;
87 }
88
89 private TestCase buildSingleTestMethod(Class testClass, String testMethodName) {
90 try {
91 TestCase testCase = (TestCase) testClass.newInstance();
92 testCase.setName(testMethodName);
93 return testCase;
94 } catch (IllegalAccessException e) {
95 runFailed("Could not access test class. Class: " + testClass.getName());
96 } catch (InstantiationException e) {
97 runFailed("Could not instantiate test class. Class: " + testClass.getName());
98 }
99
100 return null;
101 }
102
103 private boolean shouldRunSingleTestMethod(String testMethodName,
104 Class<? extends Test> testClass) {
105 return testMethodName != null && TestCase.class.isAssignableFrom(testClass);
106 }
107
108 private Test getTest(Class clazz) {
109 if (TestSuiteProvider.class.isAssignableFrom(clazz)) {
110 try {
111 TestSuiteProvider testSuiteProvider =
112 (TestSuiteProvider) clazz.getConstructor().newInstance();
113 return testSuiteProvider.getTestSuite();
114 } catch (InstantiationException e) {
115 runFailed("Could not instantiate test suite provider. Class: " + clazz.getName());
116 } catch (IllegalAccessException e) {
117 runFailed("Illegal access of test suite provider. Class: " + clazz.getName());
118 } catch (InvocationTargetException e) {
119 runFailed("Invocation exception test suite provider. Class: " + clazz.getName());
120 } catch (NoSuchMethodException e) {
121 runFailed("No such method on test suite provider. Class: " + clazz.getName());
122 }
123 }
124 return getTest(clazz.getName());
125 }
126
127 protected TestResult createTestResult() {
128 if (mSkipExecution) {
129 return new NoExecTestResult();
130 }
131 return new TestResult();
132 }
133
134 void setSkipExecution(boolean skip) {
135 mSkipExecution = skip;
136 }
137
138 public List<TestCase> getTestCases() {
139 return mTestCases;
140 }
141
142 public String getTestClassName() {
143 return mTestClassName;
144 }
145
146 public TestResult getTestResult() {
147 return mTestResult;
148 }
149
150 public void runTest() {
151 runTest(createTestResult());
152 }
153
154 public void runTest(TestResult testResult) {
155 mTestResult = testResult;
156
157 for (TestListener testListener : mTestListeners) {
158 mTestResult.addListener(testListener);
159 }
160
161 for (TestCase testCase : mTestCases) {
162 setContextIfAndroidTestCase(testCase, mContext);
163 setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
164 testCase.run(mTestResult);
165 }
166 }
167
168 private void setContextIfAndroidTestCase(Test test, Context context) {
169 if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
170 ((AndroidTestCase) test).setContext(context);
171 }
172 }
173
174 public void setContext(Context context) {
175 mContext = context;
176 }
177
178 private void setInstrumentationIfInstrumentationTestCase(
179 Test test, Instrumentation instrumentation) {
180 if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
181 ((InstrumentationTestCase) test).injectInsrumentation(instrumentation);
182 }
183 }
184
185 public void setInstrumentaiton(Instrumentation instrumentation) {
186 mInstrumentation = instrumentation;
187 }
188
189 @Override
190 protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
191 return mContext.getClassLoader().loadClass(suiteClassName);
192 }
193
194 public void testStarted(String testName) {
195 }
196
197 public void testEnded(String testName) {
198 }
199
200 public void testFailed(int status, Test test, Throwable t) {
201 }
202
203 protected void runFailed(String message) {
204 throw new RuntimeException(message);
205 }
206}