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