1e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/* 2e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Copyright (C) 2012 The Android Open Source Project 3e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 4e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 5e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * you may not use this file except in compliance with the License. 6e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * You may obtain a copy of the License at 7e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 8e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 9e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 10e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Unless required by applicable law or agreed to in writing, software 11e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 12e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * See the License for the specific language governing permissions and 14e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * limitations under the License. 15e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 16e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 17e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupackage com.android.uiautomator.testrunner; 18e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 19e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.app.Activity; 20e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.app.IInstrumentationWatcher; 21e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.app.Instrumentation; 22e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.content.ComponentName; 23e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.os.Bundle; 24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.os.Debug; 25e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.os.IBinder; 26e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.test.RepetitiveTest; 27e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.util.Log; 28e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 29e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport com.android.uiautomator.core.UiDevice; 30e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 31e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.AssertionFailedError; 32e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.Test; 33e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestCase; 34e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestListener; 35e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestResult; 36e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.runner.BaseTestRunner; 37e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.textui.ResultPrinter; 38e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 39e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.io.ByteArrayOutputStream; 40e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.io.PrintStream; 41e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.lang.Thread.UncaughtExceptionHandler; 42e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.lang.reflect.Method; 43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.ArrayList; 44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.List; 45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 46ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu/** 47ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu * @hide 48ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu */ 49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupublic class UiAutomatorTestRunner { 50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 51e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String LOGTAG = UiAutomatorTestRunner.class.getSimpleName(); 52e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int EXIT_OK = 0; 53e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int EXIT_EXCEPTION = -1; 54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private boolean mDebug; 56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private Bundle mParams = null; 57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private UiDevice mUiDevice; 58e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private List<String> mTestClasses = null; 59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private FakeInstrumentationWatcher mWatcher = new FakeInstrumentationWatcher(); 60e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private IAutomationSupport mAutomationSupport = new IAutomationSupport() { 61e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 62e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void sendStatus(int resultCode, Bundle status) { 63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mWatcher.instrumentationStatus(null, resultCode, status); 64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu }; 66e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private List<TestListener> mTestListeners = new ArrayList<TestListener>(); 67e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 68e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void run(List<String> testClasses, Bundle params, boolean debug) { 69e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void uncaughtException(Thread thread, Throwable ex) { 72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Log.e(LOGTAG, "uncaught exception", ex); 73e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Bundle results = new Bundle(); 74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu results.putString("shortMsg", ex.getClass().getName()); 75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu results.putString("longMsg", ex.getMessage()); 76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mWatcher.instrumentationFinished(null, 0, results); 77e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // bailing on uncaught exception 78e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.exit(EXIT_EXCEPTION); 79e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 80e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu }); 81e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 82e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestClasses = testClasses; 83e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mParams = params; 84e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mDebug = debug; 85e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu start(); 86e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.exit(EXIT_OK); 87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Called after all test classes are in place, ready to test 91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void start() { 93e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu TestCaseCollector collector = getTestCaseCollector(this.getClass().getClassLoader()); 94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 95e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu collector.addTestClasses(mTestClasses); 96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (ClassNotFoundException e) { 97e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // will be caught by uncaught handler 98e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new RuntimeException(e.getMessage(), e); 99e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (mDebug) { 101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Debug.waitForDebugger(); 102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mUiDevice = UiDevice.getInstance(); 104e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu List<TestCase> testCases = collector.getTestCases(); 105e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Bundle testRunOutput = new Bundle(); 106e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 107e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu PrintStream writer = new PrintStream(byteArrayOutputStream); 108e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 109e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu StringResultPrinter resultPrinter = new StringResultPrinter(writer); 110e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 111e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu TestResult testRunResult = new TestResult(); 112e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // add test listeners 113e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunResult.addListener(new WatcherResultPrinter(testCases.size())); 114e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunResult.addListener(resultPrinter); 115e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // add all custom listeners 116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (TestListener listener : mTestListeners) { 117e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunResult.addListener(listener); 118e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 119e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu long startTime = System.currentTimeMillis(); 120e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 121e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // run tests for realz! 122e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (TestCase testCase : testCases) { 123e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu prepareTestCase(testCase); 124e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testCase.run(testRunResult); 125e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 126e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu long runTime = System.currentTimeMillis() - startTime; 127e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 128e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu resultPrinter.print2(testRunResult, runTime); 129e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (Throwable t) { 130e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // catch all exceptions so a more verbose error message can be outputted 131e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu writer.println(String.format("Test run aborted due to unexpected exception: %s", 132e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu t.getMessage())); 133e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu t.printStackTrace(writer); 134e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } finally { 135e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 136e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\nTest results for %s=%s", 137e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu getClass().getSimpleName(), 138e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu byteArrayOutputStream.toString())); 139e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu writer.close(); 140e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mAutomationSupport.sendStatus(Activity.RESULT_OK, testRunOutput); 141e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 142e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 143e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 144e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // copy & pasted from com.android.commands.am.Am 145e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private class FakeInstrumentationWatcher implements IInstrumentationWatcher { 146e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 147e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private boolean mRawMode = true; 148e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 149e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 150e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public IBinder asBinder() { 151e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new UnsupportedOperationException("I'm just a fake!"); 152e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 153e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 154e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 155e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { 156e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu synchronized (this) { 157e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printer mode? 158e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String pretty = null; 159e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mRawMode && results != null) { 160e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 161e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (pretty != null) { 163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.print(pretty); 164e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 165e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (results != null) { 166e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (String key : results.keySet()) { 167e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_STATUS: " + key + "=" 168e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu + results.get(key)); 169e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 170e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 171e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode); 172e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 173e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu notifyAll(); 174e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 175e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 176e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 177e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 178e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) { 179e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu synchronized (this) { 180e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printer mode? 181e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String pretty = null; 182e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mRawMode && results != null) { 183e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 184e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 185e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (pretty != null) { 186e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println(pretty); 187e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 188e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (results != null) { 189e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (String key : results.keySet()) { 190e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_RESULT: " + key + "=" 191e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu + results.get(key)); 192e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 193e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 194e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_CODE: " + resultCode); 195e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 196e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu notifyAll(); 197e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 198e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 199e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 200e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 201e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Copy & pasted from InstrumentationTestRunner.WatcherResultPrinter 202e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private class WatcherResultPrinter implements TestListener { 203e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 204e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_TOTAL = "numtests"; 205e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NAME_CLASS = "class"; 206e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_CURRENT = "current"; 207e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NAME_TEST = "test"; 208e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations"; 209e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_VALUE_ID = "UiAutomatorTestRunner"; 210e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_STACK = "stack"; 211e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 212e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_START = 1; 213e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_ERROR = -1; 214e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_FAILURE = -2; 215e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 216e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private final Bundle mResultTemplate; 217e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Bundle mTestResult; 218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int mTestNum = 0; 219e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int mTestResultCode = 0; 220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String mTestClass = null; 221e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 222e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public WatcherResultPrinter(int numTests) { 223e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate = new Bundle(); 224e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID); 225e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests); 226e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 227e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 228e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 229e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * send a status for the start of a each test, so long tests can be seen 230e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * as "running" 231e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 232e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 233e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void startTest(Test test) { 234e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String testClass = test.getClass().getName(); 235e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String testName = ((TestCase) test).getName(); 236e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult = new Bundle(mResultTemplate); 237e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_NAME_CLASS, testClass); 238e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_NAME_TEST, testName); 239e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putInt(REPORT_KEY_NUM_CURRENT, ++mTestNum); 240e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 241e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (testClass != null && !testClass.equals(mTestClass)) { 242e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 243e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\n%s:", testClass)); 244e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestClass = testClass; 245e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 246e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ""); 247e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 248e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 249e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Method testMethod = null; 250e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 251e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testMethod = test.getClass().getMethod(testName); 252e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Report total number of iterations, if test is repetitive 253e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (testMethod.isAnnotationPresent(RepetitiveTest.class)) { 254e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int numIterations = testMethod.getAnnotation(RepetitiveTest.class) 255e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .numIterations(); 256e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations); 257e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 258e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (NoSuchMethodException e) { 259e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // ignore- the test with given name does not exist. Will be 260e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // handled during test 261e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // execution 262e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 263e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 264e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mAutomationSupport.sendStatus(REPORT_VALUE_RESULT_START, mTestResult); 265e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = 0; 266e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 267e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 268e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 269e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addError(Test test, Throwable t) { 270e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t)); 271e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = REPORT_VALUE_RESULT_ERROR; 272e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 273e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 274e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\nError in %s:\n%s", 275e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t))); 276e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 277e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 278e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 279e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addFailure(Test test, AssertionFailedError t) { 280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t)); 281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = REPORT_VALUE_RESULT_FAILURE; 282e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 283e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 284e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\nFailure in %s:\n%s", 285e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t))); 286e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 287e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 288e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 289e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void endTest(Test test) { 290e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (mTestResultCode == 0) { 291e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "."); 292e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 293e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mAutomationSupport.sendStatus(mTestResultCode, mTestResult); 294e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 295e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 296e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 297e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 298e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // copy pasted from InstrumentationTestRunner 299e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private class StringResultPrinter extends ResultPrinter { 300e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 301e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public StringResultPrinter(PrintStream writer) { 302e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu super(writer); 303e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 304e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 305e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu synchronized void print2(TestResult result, long runTime) { 306e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu printHeader(runTime); 307e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu printFooter(result); 308e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 309e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 310e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 311e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) { 312e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return new TestCaseCollector(classLoader, new UiAutomatorTestCaseFilter()); 313e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 314e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 315e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void addTestListener(TestListener listener) { 316e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mTestListeners.contains(listener)) { 317e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestListeners.add(listener); 318e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 319e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 320e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 321e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void removeTestListener(TestListener listener) { 322e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestListeners.remove(listener); 323e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 324e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 325e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 326e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * subclass may override this method to perform further preparation 327e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 328e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param testCase 329e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 330e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void prepareTestCase(TestCase testCase) { 331e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setAutomationSupport(mAutomationSupport); 332e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setUiDevice(mUiDevice); 333e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setParams(mParams); 334e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu} 336