From 31989aa81fe83b8ca21618eb831fc6e60f2d4b12 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Mon, 3 Feb 2014 15:19:06 -0800 Subject: Add support for specifying runlisteners via AndroidManifest. Also refactor existing listener support to simplify. Change-Id: Ib4ec9ceeba3c68b8a700161c6300ea1ab5d944a3 --- .../support/test/runner/AndroidJUnitRunner.java | 89 ++++++++++++++++------ 1 file changed, 67 insertions(+), 22 deletions(-) (limited to 'support/src') diff --git a/support/src/android/support/test/runner/AndroidJUnitRunner.java b/support/src/android/support/test/runner/AndroidJUnitRunner.java index f3c0ceb..5a600ed 100644 --- a/support/src/android/support/test/runner/AndroidJUnitRunner.java +++ b/support/src/android/support/test/runner/AndroidJUnitRunner.java @@ -18,6 +18,9 @@ package android.support.test.runner; import android.app.Activity; import android.app.Instrumentation; +import android.content.pm.InstrumentationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.os.Debug; import android.os.Looper; @@ -129,6 +132,13 @@ import java.util.List; * To specify EMMA code coverage results file path: * -e coverageFile /sdcard/myFile.ec *

+ * To specify one or more {@link RunListener}s to observe the test run: + * -e listener com.foo.Listener,com.foo.Listener2 + *

+ * OR, specify the multiple listeners in the AndroidManifest via a meta-data tag: + * instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" ... + * meta-data android:name="listener" + * android:value="com.foo.Listener,com.foo.Listener2" */ public class AndroidJUnitRunner extends Instrumentation { @@ -143,7 +153,7 @@ public class AndroidJUnitRunner extends Instrumentation { private static final String ARGUMENT_COVERAGE_PATH = "coverageFile"; private static final String ARGUMENT_SUITE_ASSIGNMENT = "suiteAssignment"; private static final String ARGUMENT_DEBUG = "debug"; - private static final String ARGUMENT_EXTRA_LISTENER = "extraListener"; + private static final String ARGUMENT_LISTENER = "listener"; private static final String ARGUMENT_TEST_PACKAGE = "package"; // TODO: consider supporting 'count' from InstrumentationTestRunner @@ -238,59 +248,94 @@ public class AndroidJUnitRunner extends Instrumentation { private void addListeners(List listeners, JUnitCore testRunner, PrintStream writer) { if (getBooleanArgument(ARGUMENT_SUITE_ASSIGNMENT)) { - addListener(listeners, testRunner, new SuiteAssignmentPrinter(this)); + listeners.add(new SuiteAssignmentPrinter(this)); } else { - addListener(listeners, testRunner, new TextListener(writer)); - addListener(listeners, testRunner, new LogRunListener()); - addListener(listeners, testRunner, new InstrumentationResultPrinter(this)); - addDelayListener(listeners, testRunner); - addCoverageListener(listeners, testRunner); + listeners.add(new TextListener(writer)); + listeners.add(new LogRunListener()); + listeners.add(new InstrumentationResultPrinter(this)); + addDelayListener(listeners); + addCoverageListener(listeners); } - addExtraListenersFromArg(listeners, testRunner, writer); - } + addListenersFromArg(listeners, writer); + addListenersFromManifest(listeners, writer); - private void addListener(List list, JUnitCore testRunner, RunListener listener) { - list.add(listener); - testRunner.addListener(listener); + for (RunListener listener : listeners) { + testRunner.addListener(listener); + } } - private void addCoverageListener(List list, JUnitCore testRunner) { + private void addCoverageListener(List list) { if (getBooleanArgument(ARGUMENT_COVERAGE)) { String coverageFilePath = getArguments().getString(ARGUMENT_COVERAGE_PATH); - addListener(list, testRunner, new CoverageListener(this, coverageFilePath)); + list.add(new CoverageListener(this, coverageFilePath)); } } /** * Sets up listener to inject {@link #ARGUMENT_DELAY_MSEC}, if specified. - * @param testRunner */ - private void addDelayListener(List list, JUnitCore testRunner) { + private void addDelayListener(List list) { try { Object delay = getArguments().get(ARGUMENT_DELAY_MSEC); // Accept either string or int if (delay != null) { int delayMsec = Integer.parseInt(delay.toString()); - addListener(list, testRunner, new DelayInjector(delayMsec)); + list.add(new DelayInjector(delayMsec)); } } catch (NumberFormatException e) { Log.e(LOG_TAG, "Invalid delay_msec parameter", e); } } - private void addExtraListenersFromArg(List listeners, JUnitCore testRunner, + /** + * Add extra {@link RunListener}s specified via command line + */ + private void addListenersFromArg(List listeners, PrintStream writer) { - String extraListenerList = getArguments().getString(ARGUMENT_EXTRA_LISTENER); + addListenersFromClassString(getArguments().getString(ARGUMENT_LISTENER), + listeners, writer); + } + + /** + * Load the listeners specified via meta-data name="listener" in the AndroidManifest. + */ + private void addListenersFromManifest(List listeners, + PrintStream writer) { + PackageManager pm = getContext().getPackageManager(); + try { + InstrumentationInfo instrInfo = pm.getInstrumentationInfo(getComponentName(), + PackageManager.GET_META_DATA); + Bundle b = instrInfo.metaData; + if (b == null) { + return; + } + String extraListenerList = b.getString(ARGUMENT_LISTENER); + addListenersFromClassString(extraListenerList, listeners, writer); + } catch (NameNotFoundException e) { + // should never happen + Log.wtf(LOG_TAG, String.format("Could not find component %s", getComponentName())); + } + } + + /** + * Add extra {@link RunListener}s to the testRunner as given in the csv class name list + * + * @param extraListenerList the CSV class name of {@link RunListener}s to add + * @param writer the {@link PrintStream} to dump errors to + * @param listeners the {@link List} to add listeners to + */ + private void addListenersFromClassString(String extraListenerList, + List listeners, PrintStream writer) { if (extraListenerList == null) { return; } for (String listenerName : extraListenerList.split(",")) { - addExtraListener(listeners, testRunner, writer, listenerName); + addListenerByClassName(listeners, writer, listenerName); } } - private void addExtraListener(List listeners, JUnitCore testRunner, + private void addListenerByClassName(List listeners, PrintStream writer, String extraListener) { if (extraListener == null || extraListener.length() == 0) { return; @@ -325,7 +370,7 @@ public class AndroidJUnitRunner extends Instrumentation { return; } - addListener(listeners, testRunner, l); + listeners.add(l); } private void reportRunEnded(List listeners, PrintStream writer, Bundle results) { -- cgit v1.2.3