• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import junit.framework.Test;
25 import junit.framework.TestCase;
26 import junit.framework.TestListener;
27 import junit.framework.TestResult;
28 import junit.framework.TestSuite;
29 import junit.runner.BaseTestRunner;
30 
31 import java.lang.reflect.InvocationTargetException;
32 import java.util.List;
33 
34 public 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;
44     private PerformanceResultsWriter mPerfWriter;
45 
46     @SuppressWarnings("unchecked")
setTestClassName(String testClassName, String testMethodName)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 
setTest(Test test)59     public void setTest(Test test) {
60         setTest(test, test.getClass());
61     }
62 
setTest(Test test, Class<? extends Test> testClass)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 
clearTestListeners()72     public void clearTestListeners() {
73         mTestListeners.clear();
74     }
75 
addTestListener(TestListener testListener)76     public void addTestListener(TestListener testListener) {
77         if (testListener != null) {
78             mTestListeners.add(testListener);
79         }
80     }
81 
82     @SuppressWarnings("unchecked")
loadTestClass(String testClassName)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 
buildSingleTestMethod(Class testClass, String testMethodName)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 
shouldRunSingleTestMethod(String testMethodName, Class<? extends Test> testClass)106     private boolean shouldRunSingleTestMethod(String testMethodName,
107             Class<? extends Test> testClass) {
108         return testMethodName != null && TestCase.class.isAssignableFrom(testClass);
109     }
110 
getTest(Class clazz)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 
createTestResult()130     protected TestResult createTestResult() {
131         if (mSkipExecution) {
132             return new NoExecTestResult();
133         }
134         return new TestResult();
135     }
136 
setSkipExecution(boolean skip)137     void setSkipExecution(boolean skip) {
138         mSkipExecution = skip;
139     }
140 
getTestCases()141     public List<TestCase> getTestCases() {
142         return mTestCases;
143     }
144 
getTestClassName()145     public String getTestClassName() {
146         return mTestClassName;
147     }
148 
getTestResult()149     public TestResult getTestResult() {
150         return mTestResult;
151     }
152 
runTest()153     public void runTest() {
154         runTest(createTestResult());
155     }
156 
runTest(TestResult testResult)157     public void runTest(TestResult testResult) {
158         mTestResult = testResult;
159 
160         for (TestListener testListener : mTestListeners) {
161             mTestResult.addListener(testListener);
162         }
163 
164         Context testContext = mInstrumentation == null ? mContext : mInstrumentation.getContext();
165         for (TestCase testCase : mTestCases) {
166             setContextIfAndroidTestCase(testCase, mContext, testContext);
167             setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
168             setPerformanceWriterIfPerformanceCollectorTestCase(testCase, mPerfWriter);
169             testCase.run(mTestResult);
170         }
171     }
172 
setContextIfAndroidTestCase(Test test, Context context, Context testContext)173     private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) {
174         if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
175             ((AndroidTestCase) test).setContext(context);
176             ((AndroidTestCase) test).setTestContext(testContext);
177         }
178     }
179 
setContext(Context context)180     public void setContext(Context context) {
181         mContext = context;
182     }
183 
setInstrumentationIfInstrumentationTestCase( Test test, Instrumentation instrumentation)184     private void setInstrumentationIfInstrumentationTestCase(
185             Test test, Instrumentation instrumentation) {
186         if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
187             ((InstrumentationTestCase) test).injectInstrumentation(instrumentation);
188         }
189     }
190 
setPerformanceWriterIfPerformanceCollectorTestCase( Test test, PerformanceResultsWriter writer)191     private void setPerformanceWriterIfPerformanceCollectorTestCase(
192             Test test, PerformanceResultsWriter writer) {
193         if (PerformanceCollectorTestCase.class.isAssignableFrom(test.getClass())) {
194             ((PerformanceCollectorTestCase) test).setPerformanceResultsWriter(writer);
195         }
196     }
197 
setInstrumentation(Instrumentation instrumentation)198     public void setInstrumentation(Instrumentation instrumentation) {
199         mInstrumentation = instrumentation;
200     }
201 
202     /**
203      * @deprecated Incorrect spelling,
204      * use {@link #setInstrumentation(android.app.Instrumentation)} instead.
205      */
206     @Deprecated
setInstrumentaiton(Instrumentation instrumentation)207     public void setInstrumentaiton(Instrumentation instrumentation) {
208         setInstrumentation(instrumentation);
209     }
210 
211     /**
212      * {@hide} Pending approval for public API.
213      */
setPerformanceResultsWriter(PerformanceResultsWriter writer)214     public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
215         mPerfWriter = writer;
216     }
217 
218     @Override
loadSuiteClass(String suiteClassName)219     protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
220         return mContext.getClassLoader().loadClass(suiteClassName);
221     }
222 
testStarted(String testName)223     public void testStarted(String testName) {
224     }
225 
testEnded(String testName)226     public void testEnded(String testName) {
227     }
228 
testFailed(int status, Test test, Throwable t)229     public void testFailed(int status, Test test, Throwable t) {
230     }
231 
runFailed(String message)232     protected void runFailed(String message) {
233         throw new RuntimeException(message);
234     }
235 }
236