UiAutomatorTestRunner.java revision 71aebfa11443a9a04777cde3d9c7e29cdbb5d447
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; 2589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.os.HandlerThread; 26e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.os.IBinder; 27d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavineimport android.os.SystemClock; 28e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.test.RepetitiveTest; 29e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.util.Log; 30e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 31cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhuimport com.android.uiautomator.core.ShellUiAutomatorBridge; 32f406deb12db531785300f04e219fef28ef60b126Maxim Siniavineimport com.android.uiautomator.core.Tracer; 3389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport com.android.uiautomator.core.UiAutomationShellWrapper; 34e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport com.android.uiautomator.core.UiDevice; 35e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 3648c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.io.ByteArrayOutputStream; 3748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.io.PrintStream; 3848c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.lang.Thread.UncaughtExceptionHandler; 3948c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.lang.reflect.Method; 4048c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.util.ArrayList; 4148c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtazimport java.util.List; 4248c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz 43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.AssertionFailedError; 44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.Test; 45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestCase; 46e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestListener; 47e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.framework.TestResult; 48e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.runner.BaseTestRunner; 49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport junit.textui.ResultPrinter; 50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 51ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu/** 52ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu * @hide 53ddc1008f06fd2a875037026490ce1f848a442572Guang Zhu */ 54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupublic class UiAutomatorTestRunner { 55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String LOGTAG = UiAutomatorTestRunner.class.getSimpleName(); 57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int EXIT_OK = 0; 58e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int EXIT_EXCEPTION = -1; 59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 6089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread"; 6189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov 62e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private boolean mDebug; 6348c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private boolean mMonkey; 64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private Bundle mParams = null; 65e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private UiDevice mUiDevice; 66e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private List<String> mTestClasses = null; 6748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final FakeInstrumentationWatcher mWatcher = new FakeInstrumentationWatcher(); 6848c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final IAutomationSupport mAutomationSupport = new IAutomationSupport() { 69e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 70e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void sendStatus(int resultCode, Bundle status) { 71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mWatcher.instrumentationStatus(null, resultCode, status); 72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 73e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu }; 7448c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final List<TestListener> mTestListeners = new ArrayList<TestListener>(); 75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 7689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov private HandlerThread mHandlerThread; 7789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov 7848c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz public void run(List<String> testClasses, Bundle params, boolean debug, boolean monkey) { 79e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 80e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 81e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void uncaughtException(Thread thread, Throwable ex) { 82e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Log.e(LOGTAG, "uncaught exception", ex); 83e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Bundle results = new Bundle(); 84e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu results.putString("shortMsg", ex.getClass().getName()); 85e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu results.putString("longMsg", ex.getMessage()); 86e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mWatcher.instrumentationFinished(null, 0, results); 87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // bailing on uncaught exception 88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.exit(EXIT_EXCEPTION); 89e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 90e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu }); 91e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestClasses = testClasses; 93e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mParams = params; 94e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mDebug = debug; 9548c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz mMonkey = monkey; 96e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu start(); 97e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.exit(EXIT_OK); 98e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 99e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Called after all test classes are in place, ready to test 102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void start() { 104e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu TestCaseCollector collector = getTestCaseCollector(this.getClass().getClassLoader()); 105e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 106e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu collector.addTestClasses(mTestClasses); 107e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (ClassNotFoundException e) { 108e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // will be caught by uncaught handler 109e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new RuntimeException(e.getMessage(), e); 110e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 111e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (mDebug) { 112e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Debug.waitForDebugger(); 113e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 11489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME); 11589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov mHandlerThread.setDaemon(true); 11689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov mHandlerThread.start(); 11789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper(); 11889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov automationWrapper.connect(); 119f406deb12db531785300f04e219fef28ef60b126Maxim Siniavine 12071aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz long startTime = SystemClock.uptimeMillis(); 121d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine TestResult testRunResult = new TestResult(); 122d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine ResultReporter resultPrinter; 123d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine String outputFormat = mParams.getString("outputFormat"); 12471aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz List<TestCase> testCases = collector.getTestCases(); 12571aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz Bundle testRunOutput = new Bundle(); 126d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine if ("simple".equals(outputFormat)) { 127d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine resultPrinter = new SimpleResultPrinter(System.out, true); 128d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } else { 129d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine resultPrinter = new WatcherResultPrinter(testCases.size()); 130d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 131d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine try { 13271aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz automationWrapper.setRunAsMonkey(mMonkey); 13371aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz mUiDevice = UiDevice.getInstance(); 13471aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation())); 13571aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz 13671aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz String traceType = mParams.getString("traceOutputMode"); 13771aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz if(traceType != null) { 13871aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType); 13971aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) { 14071aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz String filename = mParams.getString("traceLogFilename"); 14171aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz if (filename == null) { 14271aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz throw new RuntimeException("Name of log file not specified. " + 14371aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz "Please specify it using traceLogFilename parameter"); 14471aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz } 14571aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz Tracer.getInstance().setOutputFilename(filename); 14671aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz } 14771aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz Tracer.getInstance().setOutputMode(mode); 14871aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz } 14971aebfa11443a9a04777cde3d9c7e29cdbb5d447Adam Momtaz 150e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // add test listeners 151e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunResult.addListener(resultPrinter); 152e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // add all custom listeners 153e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (TestListener listener : mTestListeners) { 154e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testRunResult.addListener(listener); 155e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 156e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 157e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // run tests for realz! 158e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (TestCase testCase : testCases) { 159e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu prepareTestCase(testCase); 160e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testCase.run(testRunResult); 161e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (Throwable t) { 163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // catch all exceptions so a more verbose error message can be outputted 164d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine resultPrinter.printUnexpectedError(t); 165e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } finally { 166d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine long runTime = SystemClock.uptimeMillis() - startTime; 167d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine resultPrinter.print(testRunResult, runTime, testRunOutput); 16889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov automationWrapper.disconnect(); 16948c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz automationWrapper.setRunAsMonkey(false); 17089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov mHandlerThread.quit(); 171e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 172e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 173e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 174e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // copy & pasted from com.android.commands.am.Am 175e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private class FakeInstrumentationWatcher implements IInstrumentationWatcher { 176e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 17748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final boolean mRawMode = true; 178e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 179e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 180e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public IBinder asBinder() { 181e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu throw new UnsupportedOperationException("I'm just a fake!"); 182e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 183e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 184e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 185e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { 186e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu synchronized (this) { 187e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printer mode? 188e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String pretty = null; 189e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mRawMode && results != null) { 190e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 191e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 192e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (pretty != null) { 193e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.print(pretty); 194e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 195e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (results != null) { 196e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (String key : results.keySet()) { 197e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_STATUS: " + key + "=" 198e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu + results.get(key)); 199e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 200e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 201e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode); 202e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 203e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu notifyAll(); 204e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 205e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 206e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 207e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 208e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) { 209e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu synchronized (this) { 210e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printer mode? 211e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String pretty = null; 212e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mRawMode && results != null) { 213e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 214e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 215e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (pretty != null) { 216e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println(pretty); 217e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (results != null) { 219e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (String key : results.keySet()) { 220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_RESULT: " + key + "=" 221e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu + results.get(key)); 222e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 223e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 224e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu System.out.println("INSTRUMENTATION_CODE: " + resultCode); 225e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 226e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu notifyAll(); 227e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 228e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 229e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 230e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 231d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine private interface ResultReporter extends TestListener { 232d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void print(TestResult result, long runTime, Bundle testOutput); 233d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void printUnexpectedError(Throwable t); 234d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 235d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 236e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Copy & pasted from InstrumentationTestRunner.WatcherResultPrinter 237d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine private class WatcherResultPrinter implements ResultReporter { 238e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 239e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_TOTAL = "numtests"; 240e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NAME_CLASS = "class"; 241e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_CURRENT = "current"; 242e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NAME_TEST = "test"; 243e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations"; 244e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_VALUE_ID = "UiAutomatorTestRunner"; 245e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final String REPORT_KEY_STACK = "stack"; 246e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 247e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_START = 1; 248e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_ERROR = -1; 249e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private static final int REPORT_VALUE_RESULT_FAILURE = -2; 250e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 251e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private final Bundle mResultTemplate; 252e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Bundle mTestResult; 253e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int mTestNum = 0; 254e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int mTestResultCode = 0; 255e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String mTestClass = null; 256e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 25748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final SimpleResultPrinter mPrinter; 25848c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final ByteArrayOutputStream mStream; 25948c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final PrintStream mWriter; 260d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 261e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public WatcherResultPrinter(int numTests) { 262e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate = new Bundle(); 263e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID); 264e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests); 265d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 266d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mStream = new ByteArrayOutputStream(); 267d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mWriter = new PrintStream(mStream); 268d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter = new SimpleResultPrinter(mWriter, false); 269e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 270e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 271e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 272e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * send a status for the start of a each test, so long tests can be seen 273e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * as "running" 274e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 275e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 276e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void startTest(Test test) { 277e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String testClass = test.getClass().getName(); 278e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String testName = ((TestCase) test).getName(); 279e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult = new Bundle(mResultTemplate); 280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_NAME_CLASS, testClass); 281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_NAME_TEST, testName); 282e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putInt(REPORT_KEY_NUM_CURRENT, ++mTestNum); 283e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 284e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (testClass != null && !testClass.equals(mTestClass)) { 285e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 286e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\n%s:", testClass)); 287e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestClass = testClass; 288e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } else { 289e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ""); 290e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 291e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 292e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu Method testMethod = null; 293e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu try { 294e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu testMethod = test.getClass().getMethod(testName); 295e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Report total number of iterations, if test is repetitive 296e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (testMethod.isAnnotationPresent(RepetitiveTest.class)) { 297e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int numIterations = testMethod.getAnnotation(RepetitiveTest.class) 298e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .numIterations(); 299e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations); 300e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 301e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } catch (NoSuchMethodException e) { 302e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // ignore- the test with given name does not exist. Will be 303e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // handled during test 304e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // execution 305e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 306e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 307e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mAutomationSupport.sendStatus(REPORT_VALUE_RESULT_START, mTestResult); 308e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = 0; 309d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 310d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter.startTest(test); 311e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 312e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 313e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 314e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addError(Test test, Throwable t) { 315e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t)); 316e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = REPORT_VALUE_RESULT_ERROR; 317e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 318e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 319e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\nError in %s:\n%s", 320e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t))); 321d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 322d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter.addError(test, t); 323e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 324e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 325e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 326e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void addFailure(Test test, AssertionFailedError t) { 327e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t)); 328e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResultCode = REPORT_VALUE_RESULT_FAILURE; 329e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // pretty printing 330e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 331e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String.format("\nFailure in %s:\n%s", 332e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t))); 333d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 334d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter.addFailure(test, t); 335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 336e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 337e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 338e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public void endTest(Test test) { 339e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (mTestResultCode == 0) { 340e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "."); 341e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 342e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mAutomationSupport.sendStatus(mTestResultCode, mTestResult); 343d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 344d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter.endTest(test); 345e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 346e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 34748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz @Override 348d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void print(TestResult result, long runTime, Bundle testOutput) { 349d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mPrinter.print(result, runTime, testOutput); 350d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine testOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT, 351d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine String.format("\nTest results for %s=%s", 352d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine getClass().getSimpleName(), 353d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mStream.toString())); 354d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mWriter.close(); 355d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mAutomationSupport.sendStatus(Activity.RESULT_OK, testOutput); 356d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 357e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 35848c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz @Override 359d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void printUnexpectedError(Throwable t) { 360d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mWriter.println(String.format("Test run aborted due to unexpected exception: %s", 361d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine t.getMessage())); 362d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine t.printStackTrace(mWriter); 363d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 364d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 365e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 366d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine /** 367d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine * Class that produces the same output as JUnit when running from command line. Can be 368d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine * used when default UiAutomator output is too verbose. 369d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine */ 370d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine private class SimpleResultPrinter extends ResultPrinter implements ResultReporter { 37148c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz private final boolean mFullOutput; 372d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public SimpleResultPrinter(PrintStream writer, boolean fullOutput) { 373e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu super(writer); 374d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine mFullOutput = fullOutput; 375e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 376e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 37748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz @Override 378d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void print(TestResult result, long runTime, Bundle testOutput) { 379e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu printHeader(runTime); 380d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine if (mFullOutput) { 381d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine printErrors(result); 382d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine printFailures(result); 383d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 384e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu printFooter(result); 385e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 386d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine 38748c83ae3e5fc36138a412fc5854d543fffe80376Adam Momtaz @Override 388d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine public void printUnexpectedError(Throwable t) { 389d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine if (mFullOutput) { 390d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine getWriter().printf("Test run aborted due to unexpected exeption: %s", 391d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine t.getMessage()); 392d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine t.printStackTrace(getWriter()); 393d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 394d053117ad50d47a7f2b25be4303d945e4e9edd1eMaxim Siniavine } 395e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 396e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 397e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) { 398bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine return new TestCaseCollector(classLoader, getTestCaseFilter()); 399bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine } 400bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine 401bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine /** 402bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine * Returns an object which determines if the class and its methods should be 403bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine * accepted into the test suite. 404bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine * @return 405bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine */ 406bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine public UiAutomatorTestCaseFilter getTestCaseFilter() { 407bc81b387c8d6c464f9b2a0f4f6f3224270466181Maxim Siniavine return new UiAutomatorTestCaseFilter(); 408e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 409e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 410e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void addTestListener(TestListener listener) { 411e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (!mTestListeners.contains(listener)) { 412e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestListeners.add(listener); 413e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 414e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 415e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 416e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void removeTestListener(TestListener listener) { 417e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu mTestListeners.remove(listener); 418e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 419e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 420e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 421e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * subclass may override this method to perform further preparation 422e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 423e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @param testCase 424e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 425e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu protected void prepareTestCase(TestCase testCase) { 426e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setAutomationSupport(mAutomationSupport); 427e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setUiDevice(mUiDevice); 428e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ((UiAutomatorTestCase)testCase).setParams(mParams); 429e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 430e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu} 431