1 /*
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 
17 package android.test;
18 
19 import android.app.Instrumentation;
20 import android.content.Context;
21 import android.os.PerformanceCollector.PerformanceResultsWriter;
22 
23 import com.google.android.collect.Lists;
24 
25 import junit.framework.Test;
26 import junit.framework.TestCase;
27 import junit.framework.TestListener;
28 import junit.framework.TestResult;
29 import junit.framework.TestSuite;
30 import junit.runner.BaseTestRunner;
31 
32 import java.lang.reflect.Constructor;
33 import java.lang.reflect.InvocationTargetException;
34 import java.util.List;
35 
36 /**
37  * @deprecated Use
38  * <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
39  * AndroidJUnitRunner</a> instead. New tests should be written using the
40  * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
41  */
42 @Deprecated
43 public class AndroidTestRunner extends BaseTestRunner {
44 
45     private TestResult mTestResult;
46     private String mTestClassName;
47     private List<TestCase> mTestCases;
48     private Context mContext;
49     private boolean mSkipExecution = false;
50 
51     private List<TestListener> mTestListeners = Lists.newArrayList();
52     private Instrumentation mInstrumentation;
53     private PerformanceResultsWriter mPerfWriter;
54 
55     @SuppressWarnings("unchecked")
setTestClassName(String testClassName, String testMethodName)56     public void setTestClassName(String testClassName, String testMethodName) {
57         Class testClass = loadTestClass(testClassName);
58 
59         if (shouldRunSingleTestMethod(testMethodName, testClass)) {
60             TestCase testCase = buildSingleTestMethod(testClass, testMethodName);
61             mTestCases = Lists.newArrayList(testCase);
62             mTestClassName = testClass.getSimpleName();
63         } else {
64             setTest(getTest(testClass), testClass);
65         }
66     }
67 
setTest(Test test)68     public void setTest(Test test) {
69         setTest(test, test.getClass());
70     }
71 
setTest(Test test, Class<? extends Test> testClass)72     private void setTest(Test test, Class<? extends Test> testClass) {
73         mTestCases = (List<TestCase>) TestCaseUtil.getTests(test, true);
74         if (TestSuite.class.isAssignableFrom(testClass)) {
75             mTestClassName = TestCaseUtil.getTestName(test);
76         } else {
77             mTestClassName = testClass.getSimpleName();
78         }
79     }
80 
clearTestListeners()81     public void clearTestListeners() {
82         mTestListeners.clear();
83     }
84 
addTestListener(TestListener testListener)85     public void addTestListener(TestListener testListener) {
86         if (testListener != null) {
87             mTestListeners.add(testListener);
88         }
89     }
90 
91     @SuppressWarnings("unchecked")
loadTestClass(String testClassName)92     private Class<? extends Test> loadTestClass(String testClassName) {
93         try {
94             return (Class<? extends Test>) mContext.getClassLoader().loadClass(testClassName);
95         } catch (ClassNotFoundException e) {
96             runFailed("Could not find test class. Class: " + testClassName);
97         }
98         return null;
99     }
100 
buildSingleTestMethod(Class testClass, String testMethodName)101     private TestCase buildSingleTestMethod(Class testClass, String testMethodName) {
102         try {
103             Constructor c = testClass.getConstructor();
104             return newSingleTestMethod(testClass, testMethodName, c);
105         } catch (NoSuchMethodException e) {
106         }
107 
108         try {
109             Constructor c = testClass.getConstructor(String.class);
110             return newSingleTestMethod(testClass, testMethodName, c, testMethodName);
111         } catch (NoSuchMethodException e) {
112         }
113 
114         return null;
115     }
116 
newSingleTestMethod(Class testClass, String testMethodName, Constructor constructor, Object... args)117     private TestCase newSingleTestMethod(Class testClass, String testMethodName,
118             Constructor constructor, Object... args) {
119         try {
120             TestCase testCase = (TestCase) constructor.newInstance(args);
121             testCase.setName(testMethodName);
122             return testCase;
123         } catch (IllegalAccessException e) {
124             runFailed("Could not access test class. Class: " + testClass.getName());
125         } catch (InstantiationException e) {
126             runFailed("Could not instantiate test class. Class: " + testClass.getName());
127         } catch (IllegalArgumentException e) {
128             runFailed("Illegal argument passed to constructor. Class: " + testClass.getName());
129         } catch (InvocationTargetException e) {
130             runFailed("Constructor thew an exception. Class: " + testClass.getName());
131         }
132         return null;
133     }
134 
shouldRunSingleTestMethod(String testMethodName, Class<? extends Test> testClass)135     private boolean shouldRunSingleTestMethod(String testMethodName,
136             Class<? extends Test> testClass) {
137         return testMethodName != null && TestCase.class.isAssignableFrom(testClass);
138     }
139 
getTest(Class clazz)140     private Test getTest(Class clazz) {
141         if (TestSuiteProvider.class.isAssignableFrom(clazz)) {
142             try {
143                 TestSuiteProvider testSuiteProvider =
144                         (TestSuiteProvider) clazz.getConstructor().newInstance();
145                 return testSuiteProvider.getTestSuite();
146             } catch (InstantiationException e) {
147                 runFailed("Could not instantiate test suite provider. Class: " + clazz.getName());
148             } catch (IllegalAccessException e) {
149                 runFailed("Illegal access of test suite provider. Class: " + clazz.getName());
150             } catch (InvocationTargetException e) {
151                 runFailed("Invocation exception test suite provider. Class: " + clazz.getName());
152             } catch (NoSuchMethodException e) {
153                 runFailed("No such method on test suite provider. Class: " + clazz.getName());
154             }
155         }
156         return getTest(clazz.getName());
157     }
158 
createTestResult()159     protected TestResult createTestResult() {
160         if (mSkipExecution) {
161             return new NoExecTestResult();
162         }
163         return new TestResult();
164     }
165 
setSkipExecution(boolean skip)166     void setSkipExecution(boolean skip) {
167         mSkipExecution = skip;
168     }
169 
getTestCases()170     public List<TestCase> getTestCases() {
171         return mTestCases;
172     }
173 
getTestClassName()174     public String getTestClassName() {
175         return mTestClassName;
176     }
177 
getTestResult()178     public TestResult getTestResult() {
179         return mTestResult;
180     }
181 
runTest()182     public void runTest() {
183         runTest(createTestResult());
184     }
185 
runTest(TestResult testResult)186     public void runTest(TestResult testResult) {
187         mTestResult = testResult;
188 
189         for (TestListener testListener : mTestListeners) {
190             mTestResult.addListener(testListener);
191         }
192 
193         Context testContext = mInstrumentation == null ? mContext : mInstrumentation.getContext();
194         for (TestCase testCase : mTestCases) {
195             setContextIfAndroidTestCase(testCase, mContext, testContext);
196             setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
197             setPerformanceWriterIfPerformanceCollectorTestCase(testCase, mPerfWriter);
198             testCase.run(mTestResult);
199         }
200     }
201 
setContextIfAndroidTestCase(Test test, Context context, Context testContext)202     private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) {
203         if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
204             ((AndroidTestCase) test).setContext(context);
205             ((AndroidTestCase) test).setTestContext(testContext);
206         }
207     }
208 
setContext(Context context)209     public void setContext(Context context) {
210         mContext = context;
211     }
212 
setInstrumentationIfInstrumentationTestCase( Test test, Instrumentation instrumentation)213     private void setInstrumentationIfInstrumentationTestCase(
214             Test test, Instrumentation instrumentation) {
215         if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
216             ((InstrumentationTestCase) test).injectInstrumentation(instrumentation);
217         }
218     }
219 
setPerformanceWriterIfPerformanceCollectorTestCase( Test test, PerformanceResultsWriter writer)220     private void setPerformanceWriterIfPerformanceCollectorTestCase(
221             Test test, PerformanceResultsWriter writer) {
222         if (PerformanceCollectorTestCase.class.isAssignableFrom(test.getClass())) {
223             ((PerformanceCollectorTestCase) test).setPerformanceResultsWriter(writer);
224         }
225     }
226 
setInstrumentation(Instrumentation instrumentation)227     public void setInstrumentation(Instrumentation instrumentation) {
228         mInstrumentation = instrumentation;
229     }
230 
231     /**
232      * @deprecated Incorrect spelling,
233      * use {@link #setInstrumentation(android.app.Instrumentation)} instead.
234      */
235     @Deprecated
setInstrumentaiton(Instrumentation instrumentation)236     public void setInstrumentaiton(Instrumentation instrumentation) {
237         setInstrumentation(instrumentation);
238     }
239 
240     /**
241      * {@hide} Pending approval for public API.
242      */
setPerformanceResultsWriter(PerformanceResultsWriter writer)243     public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
244         mPerfWriter = writer;
245     }
246 
247     @Override
loadSuiteClass(String suiteClassName)248     protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
249         return mContext.getClassLoader().loadClass(suiteClassName);
250     }
251 
testStarted(String testName)252     public void testStarted(String testName) {
253     }
254 
testEnded(String testName)255     public void testEnded(String testName) {
256     }
257 
testFailed(int status, Test test, Throwable t)258     public void testFailed(int status, Test test, Throwable t) {
259     }
260 
runFailed(String message)261     protected void runFailed(String message) {
262         throw new RuntimeException(message);
263     }
264 }
265