summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Korostelev <nkorsote@google.com>2014-06-20 16:52:19 -0700
committerNick Korostelev <nkorsote@google.com>2014-08-07 21:52:07 +0000
commit4771553b614aa042d8456df1dd73aae761c106d8 (patch)
tree7b97edfdc58984fb2ac35dcac36ddf7761221c0d
parent976c4234127805d7dc9a1cdbcb42b5d9f4585771 (diff)
downloadtesting-4771553b614aa042d8456df1dd73aae761c106d8.tar.gz
Adding support for loading classes/methods from file
Added testFile argument to AndroidJunitRunner which allows to run all tests listed in a file: adb shell am instrument -w -e testFile /sdcard/tmp/testFile.txt com.android.foo/com.android.test.runner.AndroidJUnitRunner The file should contain a list of line separated test classes and methods. bug: 16031984 Change-Id: Idf3e5e12f65ed670f31dad54bf3f0e303114c755 (cherry picked from commit da785cf4556f8bfc347c8118b42c74dc0ec59f58)
-rw-r--r--support/src/android/support/test/internal/runner/ClassPathScanner.java2
-rw-r--r--support/src/android/support/test/internal/runner/TestRequestBuilder.java3
-rw-r--r--support/src/android/support/test/runner/AndroidJUnitRunner.java61
-rw-r--r--support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java2
-rw-r--r--support/tests/src/android/support/test/runner/AndroidJUnitRunnerTest.java51
5 files changed, 111 insertions, 8 deletions
diff --git a/support/src/android/support/test/internal/runner/ClassPathScanner.java b/support/src/android/support/test/internal/runner/ClassPathScanner.java
index 300c7de..ac34406 100644
--- a/support/src/android/support/test/internal/runner/ClassPathScanner.java
+++ b/support/src/android/support/test/internal/runner/ClassPathScanner.java
@@ -44,7 +44,7 @@ class ClassPathScanner {
* Tests whether or not the specified abstract pathname should be included in a class path
* entry list.
*
- * @param pathName the relative path of the class path entry
+ * @param className the relative path of the class path entry
*/
boolean accept(String className);
}
diff --git a/support/src/android/support/test/internal/runner/TestRequestBuilder.java b/support/src/android/support/test/internal/runner/TestRequestBuilder.java
index 82f007e..4a8383f 100644
--- a/support/src/android/support/test/internal/runner/TestRequestBuilder.java
+++ b/support/src/android/support/test/internal/runner/TestRequestBuilder.java
@@ -267,7 +267,7 @@ public class TestRequestBuilder {
}
/**
- * Class that filters out tests annotated with {@link RequestDevice} when running on emulator
+ * Class that filters out tests annotated with {@link RequiresDevice} when running on emulator
*/
private class RequiresDeviceFilter extends AnnotationExclusionFilter {
@@ -518,6 +518,7 @@ public class TestRequestBuilder {
* @param instr the {@link Instrumentation} to inject into any tests that require it
* @param bundle the {@link Bundle} of command line args to inject into any tests that require
* it
+ * @param skipExecution whether or not to skip actual test execution
* @param computer Helps construct Runners from classes
* @param classes the classes containing the tests
* @return a <code>Request</code> that will cause all tests in the classes to be run
diff --git a/support/src/android/support/test/runner/AndroidJUnitRunner.java b/support/src/android/support/test/runner/AndroidJUnitRunner.java
index 42cdc73..f07bf0c 100644
--- a/support/src/android/support/test/runner/AndroidJUnitRunner.java
+++ b/support/src/android/support/test/runner/AndroidJUnitRunner.java
@@ -46,7 +46,12 @@ import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;
+import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@@ -88,6 +93,11 @@ import java.util.List;
* -e class com.android.foo.FooTest,com.android.foo.TooTest
* com.android.foo/android.support.test.runner.AndroidJUnitRunner
* <p/>
+ * <b>Running all tests listed in a file:</b> adb shell am instrument -w
+ * -e testFile /sdcard/tmp/testFile.txt com.android.foo/com.android.test.runner.AndroidJUnitRunner
+ * The file should contain a list of line separated test classes and optionally methods (expected
+ * format: com.android.foo.FooClassName#testMethodName).
+ * <p/>
* <b>Running all tests in a java package:</b> adb shell am instrument -w
* -e package com.android.foo.bar
* com.android.foo/android.support.test.runner.AndroidJUnitRunner
@@ -168,16 +178,22 @@ public class AndroidJUnitRunner extends MonitoringInstrumentation {
private static final String ARGUMENT_DEBUG = "debug";
private static final String ARGUMENT_LISTENER = "listener";
private static final String ARGUMENT_TEST_PACKAGE = "package";
+ static final String ARGUMENT_TEST_FILE = "testFile";
// TODO: consider supporting 'count' from InstrumentationTestRunner
private static final String LOG_TAG = "AndroidJUnitRunner";
+ // used to separate multiple fully-qualified test case class names
+ private static final char CLASS_SEPARATOR = ',';
+ // used to separate fully-qualified test case class name, and one of its methods
+ private static final char METHOD_SEPARATOR = '#';
+
private Bundle mArguments;
@Override
public void onCreate(Bundle arguments) {
super.onCreate(arguments);
- mArguments = arguments;
+ setArguments(arguments);
specifyDexMakerCacheProperty();
start();
@@ -411,11 +427,16 @@ public class AndroidJUnitRunner extends MonitoringInstrumentation {
String testClassName = arguments.getString(ARGUMENT_TEST_CLASS);
if (testClassName != null) {
- for (String className : testClassName.split(",")) {
+ for (String className : testClassName.split(String.valueOf(CLASS_SEPARATOR))) {
parseTestClass(className, builder);
}
}
+ String testFilePath = arguments.getString(ARGUMENT_TEST_FILE);
+ if (testFilePath != null) {
+ parseTestClassesFromFile(testFilePath, builder);
+ }
+
String testPackage = arguments.getString(ARGUMENT_TEST_PACKAGE);
if (testPackage != null) {
builder.addTestPackageFilter(testPackage);
@@ -475,10 +496,10 @@ public class AndroidJUnitRunner extends MonitoringInstrumentation {
*
* @param testClassName - full package name of test class and optionally method to add.
* Expected format: com.android.TestClass#testMethod
- * @param testSuiteBuilder - builder to add tests to
+ * @param testRequestBuilder - builder to add tests to
*/
private void parseTestClass(String testClassName, TestRequestBuilder testRequestBuilder) {
- int methodSeparatorIndex = testClassName.indexOf('#');
+ int methodSeparatorIndex = testClassName.indexOf(METHOD_SEPARATOR);
if (methodSeparatorIndex > 0) {
String testMethodName = testClassName.substring(methodSeparatorIndex + 1);
@@ -489,6 +510,38 @@ public class AndroidJUnitRunner extends MonitoringInstrumentation {
}
}
+ /**
+ * Parse and load the content of a test file
+ *
+ * @param filePath path to test file contaitnig full package names of test classes and
+ * optionally methods to add.
+ * @param testRequestBuilder - builder to add tests to
+ */
+ private void parseTestClassesFromFile(String filePath, TestRequestBuilder testRequestBuilder) {
+ List<String> classes = new ArrayList<String>();
+ BufferedReader br = null;
+ String line;
+ try {
+ br = new BufferedReader(new FileReader(new File(filePath)));
+ while ((line = br.readLine()) != null) {
+ classes.add(line);
+ }
+ } catch (FileNotFoundException e) {
+ Log.e(LOG_TAG, String.format("File not found: %s", filePath), e);
+ } catch (IOException e) {
+ Log.e(LOG_TAG,
+ String.format("Something went wrong reading %s, ignoring file", filePath), e);
+ } finally {
+ if (br != null) {
+ try { br.close(); } catch (IOException e) { /* ignore */ }
+ }
+ }
+
+ for (String className : classes) {
+ parseTestClass(className, testRequestBuilder);
+ }
+ }
+
private void setupDexmakerClassloader() {
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
// must set the context classloader for apps that use a shared uid, see
diff --git a/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java b/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java
index f28c894..f58f39f 100644
--- a/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java
+++ b/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java
@@ -627,7 +627,7 @@ public class TestRequestBuilderTest {
}
/**
- * Test that {@link RequiresDevuce} filters tests as appropriate
+ * Test that {@link RequiresDevice} filters tests as appropriate
*/
@Test
public void testRequiresDevice() {
diff --git a/support/tests/src/android/support/test/runner/AndroidJUnitRunnerTest.java b/support/tests/src/android/support/test/runner/AndroidJUnitRunnerTest.java
index 7952980..245612a 100644
--- a/support/tests/src/android/support/test/runner/AndroidJUnitRunnerTest.java
+++ b/support/tests/src/android/support/test/runner/AndroidJUnitRunnerTest.java
@@ -18,17 +18,25 @@ package android.support.test.runner;
import android.content.Context;
import android.os.Bundle;
import android.support.test.internal.runner.TestRequestBuilder;
-import android.support.test.runner.AndroidJUnitRunner;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringReader;
/**
* Unit tests for {@link AndroidJUnitRunner}.
@@ -99,4 +107,45 @@ public class AndroidJUnitRunnerTest {
mAndroidJUnitRunner.buildRequest(b, mStubStream);
Mockito.verify(mMockBuilder).addTestMethod("ClassName1", "method");
}
+
+ /**
+ * Test {@link AndroidJUnitRunner#buildRequest(Bundle, PrintStream)} when
+ * class name and method name is provided along with an additional class name.
+ */
+ @Test
+ public void testBuildRequest_classAndMethodCombo() {
+ Bundle b = new Bundle();
+ b.putString(AndroidJUnitRunner.ARGUMENT_TEST_CLASS, "ClassName1#method,ClassName2");
+ mAndroidJUnitRunner.buildRequest(b, mStubStream);
+ Mockito.verify(mMockBuilder).addTestMethod("ClassName1", "method");
+ Mockito.verify(mMockBuilder).addTestClass("ClassName2");
+ }
+
+ /**
+ * Temp file used for testing
+ */
+ @Rule
+ public TemporaryFolder mTmpFolder = new TemporaryFolder();
+
+ /**
+ * Test {@link AndroidJUnitRunner#buildRequest(Bundle, PrintStream)} when
+ * multiple class and method names are provided within a test file
+ */
+ @Test
+ public void testBuildRequest_testFile() throws IOException {
+ final File file = mTmpFolder.newFile("myTestFile.txt");
+ BufferedWriter out = new BufferedWriter(new FileWriter(file));
+ out.write("ClassName3\n");
+ out.write("ClassName4#method2\n");
+ out.close();
+
+ Bundle b = new Bundle();
+ b.putString(AndroidJUnitRunner.ARGUMENT_TEST_FILE, file.getPath());
+ b.putString(AndroidJUnitRunner.ARGUMENT_TEST_CLASS, "ClassName1#method1,ClassName2");
+ mAndroidJUnitRunner.buildRequest(b, mStubStream);
+ Mockito.verify(mMockBuilder).addTestMethod("ClassName1", "method1");
+ Mockito.verify(mMockBuilder).addTestClass("ClassName2");
+ Mockito.verify(mMockBuilder).addTestClass("ClassName3");
+ Mockito.verify(mMockBuilder).addTestMethod("ClassName4", "method2");
+ }
}