blob: 0f1599aafd1c2e5679e3fd4bf7e555bdac78426b [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;
Jack Wangff1df692009-08-26 17:19:13 -070021import android.os.PerformanceCollector.PerformanceResultsWriter;
22
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.google.android.collect.Lists;
24import junit.framework.Test;
25import junit.framework.TestCase;
26import junit.framework.TestListener;
27import junit.framework.TestResult;
28import junit.framework.TestSuite;
29import junit.runner.BaseTestRunner;
30
31import java.lang.reflect.InvocationTargetException;
32import java.util.List;
33
34public class AndroidTestRunner extends BaseTestRunner {
35
36 private TestResult mTestResult;
37 private String mTestClassName;
38 private List<TestCase> mTestCases;
39 private Context mContext;
40 private boolean mSkipExecution = false;
41
42 private List<TestListener> mTestListeners = Lists.newArrayList();
43 private Instrumentation mInstrumentation;
Jack Wangff1df692009-08-26 17:19:13 -070044 private PerformanceResultsWriter mPerfWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
46 @SuppressWarnings("unchecked")
47 public void setTestClassName(String testClassName, String testMethodName) {
48 Class testClass = loadTestClass(testClassName);
49
50 if (shouldRunSingleTestMethod(testMethodName, testClass)) {
51 TestCase testCase = buildSingleTestMethod(testClass, testMethodName);
52 mTestCases = Lists.newArrayList(testCase);
53 mTestClassName = testClass.getSimpleName();
54 } else {
55 setTest(getTest(testClass), testClass);
56 }
57 }
58
59 public void setTest(Test test) {
60 setTest(test, test.getClass());
61 }
62
63 private void setTest(Test test, Class<? extends Test> testClass) {
64 mTestCases = (List<TestCase>) TestCaseUtil.getTests(test, true);
65 if (TestSuite.class.isAssignableFrom(testClass)) {
66 mTestClassName = TestCaseUtil.getTestName(test);
67 } else {
68 mTestClassName = testClass.getSimpleName();
69 }
70 }
71
72 public void clearTestListeners() {
73 mTestListeners.clear();
74 }
75
76 public void addTestListener(TestListener testListener) {
77 if (testListener != null) {
78 mTestListeners.add(testListener);
79 }
80 }
81
82 @SuppressWarnings("unchecked")
83 private Class<? extends Test> loadTestClass(String testClassName) {
84 try {
85 return (Class<? extends Test>) mContext.getClassLoader().loadClass(testClassName);
86 } catch (ClassNotFoundException e) {
87 runFailed("Could not find test class. Class: " + testClassName);
88 }
89 return null;
90 }
91
92 private TestCase buildSingleTestMethod(Class testClass, String testMethodName) {
93 try {
94 TestCase testCase = (TestCase) testClass.newInstance();
95 testCase.setName(testMethodName);
96 return testCase;
97 } catch (IllegalAccessException e) {
98 runFailed("Could not access test class. Class: " + testClass.getName());
99 } catch (InstantiationException e) {
100 runFailed("Could not instantiate test class. Class: " + testClass.getName());
101 }
102
103 return null;
104 }
105
106 private boolean shouldRunSingleTestMethod(String testMethodName,
107 Class<? extends Test> testClass) {
108 return testMethodName != null && TestCase.class.isAssignableFrom(testClass);
109 }
110
111 private Test getTest(Class clazz) {
112 if (TestSuiteProvider.class.isAssignableFrom(clazz)) {
113 try {
114 TestSuiteProvider testSuiteProvider =
115 (TestSuiteProvider) clazz.getConstructor().newInstance();
116 return testSuiteProvider.getTestSuite();
117 } catch (InstantiationException e) {
118 runFailed("Could not instantiate test suite provider. Class: " + clazz.getName());
119 } catch (IllegalAccessException e) {
120 runFailed("Illegal access of test suite provider. Class: " + clazz.getName());
121 } catch (InvocationTargetException e) {
122 runFailed("Invocation exception test suite provider. Class: " + clazz.getName());
123 } catch (NoSuchMethodException e) {
124 runFailed("No such method on test suite provider. Class: " + clazz.getName());
125 }
126 }
127 return getTest(clazz.getName());
128 }
129
130 protected TestResult createTestResult() {
131 if (mSkipExecution) {
132 return new NoExecTestResult();
133 }
134 return new TestResult();
135 }
136
137 void setSkipExecution(boolean skip) {
138 mSkipExecution = skip;
139 }
140
141 public List<TestCase> getTestCases() {
142 return mTestCases;
143 }
144
145 public String getTestClassName() {
146 return mTestClassName;
147 }
148
149 public TestResult getTestResult() {
150 return mTestResult;
151 }
152
153 public void runTest() {
154 runTest(createTestResult());
155 }
156
157 public void runTest(TestResult testResult) {
158 mTestResult = testResult;
159
160 for (TestListener testListener : mTestListeners) {
161 mTestResult.addListener(testListener);
162 }
163
Jack Wanga8db0a42009-08-17 14:19:52 -0700164 Context testContext = mInstrumentation == null ? mContext : mInstrumentation.getContext();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 for (TestCase testCase : mTestCases) {
Dmitri Plotnikov44a29dd2009-08-03 14:27:20 -0700166 setContextIfAndroidTestCase(testCase, mContext, testContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
Jack Wangff1df692009-08-26 17:19:13 -0700168 setPerformanceWriterIfPerformanceTestCase(testCase, mPerfWriter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 testCase.run(mTestResult);
170 }
171 }
172
Dmitri Plotnikov44a29dd2009-08-03 14:27:20 -0700173 private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
175 ((AndroidTestCase) test).setContext(context);
Dmitri Plotnikov44a29dd2009-08-03 14:27:20 -0700176 ((AndroidTestCase) test).setTestContext(testContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 }
178 }
179
180 public void setContext(Context context) {
181 mContext = context;
182 }
183
184 private void setInstrumentationIfInstrumentationTestCase(
185 Test test, Instrumentation instrumentation) {
186 if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
Jack Wang7aba54b2009-08-20 19:20:54 -0700187 ((InstrumentationTestCase) test).injectInstrumentation(instrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 }
189 }
190
Jack Wangff1df692009-08-26 17:19:13 -0700191 private void setPerformanceWriterIfPerformanceTestCase(
192 Test test, PerformanceResultsWriter writer) {
193 if (PerformanceTestBase.class.isAssignableFrom(test.getClass())) {
194 ((PerformanceTestBase) test).setPerformanceResultsWriter(writer);
195 }
196 }
197
Jack Wang7aba54b2009-08-20 19:20:54 -0700198 public void setInstrumentation(Instrumentation instrumentation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 mInstrumentation = instrumentation;
200 }
201
Jack Wang7aba54b2009-08-20 19:20:54 -0700202 /**
203 * @deprecated Incorrect spelling,
204 * use {@link #setInstrumentation(android.app.Instrumentation)} instead.
205 */
206 @Deprecated
207 public void setInstrumentaiton(Instrumentation instrumentation) {
208 setInstrumentation(instrumentation);
209 }
210
Jack Wangff1df692009-08-26 17:19:13 -0700211 /**
212 * {@hide} Pending approval for public API.
213 */
214 public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
215 mPerfWriter = writer;
216 }
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 @Override
219 protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
220 return mContext.getClassLoader().loadClass(suiteClassName);
221 }
222
223 public void testStarted(String testName) {
224 }
225
226 public void testEnded(String testName) {
227 }
228
229 public void testFailed(int status, Test test, Throwable t) {
230 }
231
232 protected void runFailed(String message) {
233 throw new RuntimeException(message);
234 }
235}