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