diff options
author | Brett Chabot <brettchabot@google.com> | 2014-02-03 15:19:06 -0800 |
---|---|---|
committer | Brett Chabot <brettchabot@google.com> | 2014-02-05 17:09:51 -0600 |
commit | 31989aa81fe83b8ca21618eb831fc6e60f2d4b12 (patch) | |
tree | 5ecb6c4ed21f82f5d4ca80bea016dd0bb4be5291 | |
parent | 9a137c9dc219f35fcf46da5dd6e3113f2f8750ac (diff) | |
download | testing-31989aa81fe83b8ca21618eb831fc6e60f2d4b12.tar.gz |
Add support for specifying runlisteners via AndroidManifest.
Also refactor existing listener support to simplify.
Change-Id: Ib4ec9ceeba3c68b8a700161c6300ea1ab5d944a3
4 files changed, 147 insertions, 24 deletions
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; * <b> To specify EMMA code coverage results file path:</b> * -e coverageFile /sdcard/myFile.ec * <p/> + * <b> To specify one or more {@link RunListener}s to observe the test run:</b> + * -e listener com.foo.Listener,com.foo.Listener2 + * <p/> + * <b/>OR, specify the multiple listeners in the AndroidManifest via a meta-data tag:</b> + * 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<RunListener> 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<RunListener> list, JUnitCore testRunner, RunListener listener) { - list.add(listener); - testRunner.addListener(listener); + for (RunListener listener : listeners) { + testRunner.addListener(listener); + } } - private void addCoverageListener(List<RunListener> list, JUnitCore testRunner) { + private void addCoverageListener(List<RunListener> 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<RunListener> list, JUnitCore testRunner) { + private void addDelayListener(List<RunListener> 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<RunListener> listeners, JUnitCore testRunner, + /** + * Add extra {@link RunListener}s specified via command line + */ + private void addListenersFromArg(List<RunListener> 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<RunListener> 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<RunListener> 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<RunListener> listeners, JUnitCore testRunner, + private void addListenerByClassName(List<RunListener> 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<RunListener> listeners, PrintStream writer, Bundle results) { diff --git a/support/tests/AndroidManifest.xml b/support/tests/AndroidManifest.xml index bad2879..9585a9e 100644 --- a/support/tests/AndroidManifest.xml +++ b/support/tests/AndroidManifest.xml @@ -22,8 +22,11 @@ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" android:targetPackage="android.support.test.tests" - android:label="Unit Tests for android.support.test."/> + android:label="Unit Tests for android.support.test."> + <meta-data android:name="listener" + android:value="android.support.test.internal.runner.listener.ManifestListener" /> + </instrumentation> - <uses-sdk android:minSdkVersion="8"/> + <uses-sdk android:minSdkVersion="8" /> </manifest> diff --git a/support/tests/src/android/support/test/internal/runner/listener/ManifestListener.java b/support/tests/src/android/support/test/internal/runner/listener/ManifestListener.java new file mode 100644 index 0000000..6e00381 --- /dev/null +++ b/support/tests/src/android/support/test/internal/runner/listener/ManifestListener.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.support.test.internal.runner.listener; + +import org.junit.runner.Description; +import org.junit.runner.notification.RunListener; + +/** + * A {@link RunListener} fixture used to ensure listener classes specified via meta-data + * tags in AndroidManifest are loaded and used properly. + */ +public class ManifestListener extends RunListener { + + private static boolean sRunStarted = false; + + @Override + public void testRunStarted(Description description) throws Exception { + // just do simple verification - set a boolean flag so test can verify it was called + sRunStarted = true; + } + + /** + * Return <code>true</code> if the testRunStarted method was called for any object + * of this type. Intended to be used to verify in this listener was loaded and + * invoked properly. + */ + public static boolean isRunStarted() { + return sRunStarted; + } +} diff --git a/support/tests/src/android/support/test/internal/runner/listener/ManifestListenerTest.java b/support/tests/src/android/support/test/internal/runner/listener/ManifestListenerTest.java new file mode 100644 index 0000000..bdbc3b7 --- /dev/null +++ b/support/tests/src/android/support/test/internal/runner/listener/ManifestListenerTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.support.test.internal.runner.listener; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.notification.RunListener; + +/** + * Simple test to check that specifying a {@link RunListener} via a meta-data tag + * in manifest works. + */ +public class ManifestListenerTest { + + @Test + public void testListenerInvoked() { + Assert.assertTrue(ManifestListener.isRunStarted()); + } +} |