diff --git a/runner/android_junit_runner/CHANGELOG.md b/runner/android_junit_runner/CHANGELOG.md
index 74db23aa9..629af6902 100644
--- a/runner/android_junit_runner/CHANGELOG.md
+++ b/runner/android_junit_runner/CHANGELOG.md
@@ -8,6 +8,8 @@
* Catch LinkageError when loading annotation classes (b/536117227)
+* Support filtering parameterized tests with arbitrary (non-numeric) parameter names by their root method name. (b/564761639)
+
**New Features**
* Make perfetto trace sections for tests more identifiable by prefixing with "test:" and using fully qualified class name. (b/204992764)
diff --git a/runner/android_junit_runner/java/androidx/test/internal/runner/TestRequestBuilder.java b/runner/android_junit_runner/java/androidx/test/internal/runner/TestRequestBuilder.java
index 0ed9bac6f..1a9d7e308 100644
--- a/runner/android_junit_runner/java/androidx/test/internal/runner/TestRequestBuilder.java
+++ b/runner/android_junit_runner/java/androidx/test/internal/runner/TestRequestBuilder.java
@@ -46,6 +46,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.runner.Description;
import org.junit.runner.Request;
@@ -364,6 +365,17 @@ public void removeMethod(String className, String methodName) {
/** A {@link Filter} used to filter out desired test methods from a given class */
private static class MethodFilter extends AbstractFilter {
+ /**
+ * Matches a parameterized test method name, capturing the root method name.
+ *
+ *
Parameterized runners name tests as {@code methodName[]}, where {@code }
+ * is arbitrary text, e.g. {@code [0]}, {@code [0: 1 + 2 = 3]}, {@code [dryRun=true,retries=2]}
+ * or {@code [[1, 2]]}. Since a JVM method name cannot contain {@code '['}, everything before
+ * the first {@code '['} is the root method name.
+ */
+ private static final Pattern PARAMETERIZED_SUFFIX_PATTERN =
+ Pattern.compile("^([^\\[]+)\\[.*\\]$", Pattern.DOTALL);
+
private final String className;
private Set includedMethods = new HashSet<>();
private Set excludedMethods = new HashSet<>();
@@ -408,12 +420,9 @@ public boolean evaluateTest(Description description) {
}
// Strips out the parameterized suffix if it exists
- private String stripParameterizedSuffix(String name) {
- Pattern suffixPattern = Pattern.compile(".+(\\[[0-9]+\\])$");
- if (suffixPattern.matcher(name).matches()) {
- name = name.substring(0, name.lastIndexOf('['));
- }
- return name;
+ private static String stripParameterizedSuffix(String name) {
+ Matcher matcher = PARAMETERIZED_SUFFIX_PATTERN.matcher(name);
+ return matcher.matches() ? matcher.group(1) : name;
}
public void addInclusionMethod(String methodName) {
diff --git a/runner/android_junit_runner/javatests/androidx/test/internal/runner/TestRequestBuilderTest.java b/runner/android_junit_runner/javatests/androidx/test/internal/runner/TestRequestBuilderTest.java
index a3d64d120..20bd1c222 100644
--- a/runner/android_junit_runner/javatests/androidx/test/internal/runner/TestRequestBuilderTest.java
+++ b/runner/android_junit_runner/javatests/androidx/test/internal/runner/TestRequestBuilderTest.java
@@ -338,6 +338,30 @@ public static Collection