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