118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/* 218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Copyright (C) 2012 The Android Open Source Project 318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * you may not use this file except in compliance with the License. 618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You may obtain a copy of the License at 718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Unless required by applicable law or agreed to in writing, software 1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See the License for the specific language governing permissions and 1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * limitations under the License. 1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.commands.uiautomator; 1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Bundle; 2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.Log; 2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport com.android.commands.uiautomator.Launcher.Command; 2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport com.android.uiautomator.testrunner.UiAutomatorTestRunner; 2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport dalvik.system.DexFile; 2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.IOException; 2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.ArrayList; 2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.Enumeration; 3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.List; 3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/** 3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Implementation of the runtest sub command 3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic class RunTestCommand extends Command { 3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String LOGTAG = RunTestCommand.class.getSimpleName(); 3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String OUTPUT_SIMPLE = "simple"; 4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String OUTPUT_FORMAT_KEY = "outputFormat"; 4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String CLASS_PARAM = "class"; 4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String JARS_PARAM = "jars"; 4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String DEBUG_PARAM = "debug"; 4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String RUNNER_PARAM = "runner"; 4518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String CLASS_SEPARATOR = ","; 4618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String JARS_SEPARATOR = ":"; 4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_OK = 0; 4818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_FAIL_INCOMPLETE_E = -1; 4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_FAIL_INCOMPLETE_C = -2; 5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_FAIL_NO_CLASS = -3; 5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_FAIL_RUNNER = -4; 5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final int ARG_FAIL_UNSUPPORTED = -99; 5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private final Bundle mParams = new Bundle(); 5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private final List<String> mTestClasses = new ArrayList<String>(); 5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private boolean mDebug; 5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private boolean mMonkey = false; 5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private String mRunnerClassName; 5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiAutomatorTestRunner mRunner; 6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public RunTestCommand() { 6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu super("runtest"); 6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void run(String[] args) { 6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int ret = parseArgs(args); 6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu switch (ret) { 6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case ARG_FAIL_INCOMPLETE_C: 7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Incomplete '-c' parameter."); 7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_INCOMPLETE_C); 7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case ARG_FAIL_INCOMPLETE_E: 7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Incomplete '-e' parameter."); 7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_INCOMPLETE_E); 7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu case ARG_FAIL_UNSUPPORTED: 7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Unsupported standalone parameter."); 7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_UNSUPPORTED); 8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu default: 8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu break; 8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mTestClasses.isEmpty()) { 8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu addTestClassesFromJars(); 8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mTestClasses.isEmpty()) { 8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("No test classes found."); 8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_NO_CLASS); 8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getRunner().run(mTestClasses, mParams, mDebug, mMonkey); 9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private int parseArgs(String[] args) { 9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // we are parsing for these parameters: 9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // -e <key> <value> 9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // key-value pairs 9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // special ones are: 9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // key is "class", parameter is passed onto JUnit as class name to run 10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // key is "debug", parameter will determine whether to wait for debugger 10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // to attach 10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // -c <class name> 10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // -s turns on the simple output format 10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // equivalent to -e class <class name>, i.e. passed onto JUnit 10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for (int i = 0; i < args.length; i++) { 10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (args[i].equals("-e")) { 10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (i + 2 < args.length) { 10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String key = args[++i]; 10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String value = args[++i]; 11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (CLASS_PARAM.equals(key)) { 11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu addTestClasses(value); 11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (DEBUG_PARAM.equals(key)) { 11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mDebug = "true".equals(value) || "1".equals(value); 11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (RUNNER_PARAM.equals(key)) { 11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mRunnerClassName = value; 11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else { 11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mParams.putString(key, value); 11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else { 12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ARG_FAIL_INCOMPLETE_E; 12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (args[i].equals("-c")) { 12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (i + 1 < args.length) { 12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu addTestClasses(args[++i]); 12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else { 12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ARG_FAIL_INCOMPLETE_C; 12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (args[i].equals("--monkey")) { 12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mMonkey = true; 13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else if (args[i].equals("-s")) { 13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mParams.putString(OUTPUT_FORMAT_KEY, OUTPUT_SIMPLE); 13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } else { 13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ARG_FAIL_UNSUPPORTED; 13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ARG_OK; 13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu protected UiAutomatorTestRunner getRunner() { 14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mRunner != null) { 14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mRunner; 14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 14418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mRunnerClassName == null) { 14518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mRunner = new UiAutomatorTestRunner(); 14618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mRunner; 14718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 14818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // use reflection to get the runner 14918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Object o = null; 15018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 15118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Class<?> clazz = Class.forName(mRunnerClassName); 15218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu o = clazz.newInstance(); 15318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (ClassNotFoundException cnfe) { 15418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Cannot find runner: " + mRunnerClassName); 15518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_RUNNER); 15618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (InstantiationException ie) { 15718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Cannot instantiate runner: " + mRunnerClassName); 15818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_RUNNER); 15918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (IllegalAccessException iae) { 16018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Constructor of runner " + mRunnerClassName + " is not accessibile"); 16118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_RUNNER); 16218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 16318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 16418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiAutomatorTestRunner runner = (UiAutomatorTestRunner)o; 16518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mRunner = runner; 16618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return runner; 16718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (ClassCastException cce) { 16818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.err.println("Specified runner is not subclass of " 16918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + UiAutomatorTestRunner.class.getSimpleName()); 17018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu System.exit(ARG_FAIL_RUNNER); 17118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 17218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // won't reach here 17318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return null; 17418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 17518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 17618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 17718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Add test classes from a potentially comma separated list 17818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param classes 17918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 18018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void addTestClasses(String classes) { 18118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String[] classArray = classes.split(CLASS_SEPARATOR); 18218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for (String clazz : classArray) { 18318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mTestClasses.add(clazz); 18418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 18518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 18618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 18718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 18818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Add test classes from jars passed on the command line. Use this if nothing was explicitly 18918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * specified on the command line. 19018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 19118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void addTestClassesFromJars() { 19218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String jars = mParams.getString(JARS_PARAM); 19318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (jars == null) return; 19418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 19518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String[] jarFileNames = jars.split(JARS_SEPARATOR); 19618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for (String fileName : jarFileNames) { 19718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu fileName = fileName.trim(); 19818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (fileName.isEmpty()) continue; 19918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 20018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu DexFile dexFile = new DexFile(fileName); 20118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for(Enumeration<String> e = dexFile.entries(); e.hasMoreElements();) { 20218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu String className = e.nextElement(); 20318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (isTestClass(className)) { 20418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mTestClasses.add(className); 20518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 20618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 20718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu dexFile.close(); 20818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (IOException e) { 20918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Log.w(LOGTAG, String.format("Could not read %s: %s", fileName, e.getMessage())); 21018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 21118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 21218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 21318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 21418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 21518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Tries to determine if a given class is a test class. A test class has to inherit from 21618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * UiAutomator test case and it must be a top-level class. 21718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param className 21818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return 21918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 22018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private boolean isTestClass(String className) { 22118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 22218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Class<?> clazz = this.getClass().getClassLoader().loadClass(className); 22318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (clazz.getEnclosingClass() != null) return false; 22418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getRunner().getTestCaseFilter().accept(clazz); 22518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (ClassNotFoundException e) { 22618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 22718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 22818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 22918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 23018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 23118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String detailedOptions() { 23218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return " runtest <class spec> [options]\n" 23318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " <class spec>: <JARS> < -c <CLASSES> | -e class <CLASSES> >\n" 23418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " <JARS>: a list of jar files containing test classes and dependencies. If\n" 23518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " the path is relative, it's assumed to be under /data/local/tmp. Use\n" 23618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " absolute path if the file is elsewhere. Multiple files can be\n" 23718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " specified, separated by space.\n" 23818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " <CLASSES>: a list of test class names to run, separated by comma. To\n" 23918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " a single method, use TestClass#testMethod format. The -e or -c option\n" 24018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " may be repeated. This option is not required and if not provided then\n" 24118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " all the tests in provided jars will be run automatically.\n" 24218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " options:\n" 24318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " --nohup: trap SIG_HUP, so test won't terminate even if parent process\n" 24418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " is terminated, e.g. USB is disconnected.\n" 24518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " -e debug [true|false]: wait for debugger to connect before starting.\n" 24618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " -e runner [CLASS]: use specified test runner class instead. If\n" 24718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " unspecified, framework default runner will be used.\n" 24818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.\n" 24918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " May be repeated.\n" 25018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu + " -e outputFormat simple | -s: enabled less verbose JUnit style output.\n"; 25118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 25218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 25318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 25418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String shortHelp() { 25518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return "executes UI automation tests"; 25618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 25718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 25818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu} 259