@Test- Unique ID:
[engine:<engine-name>][class:<quantified-class-name>]/[method:<method-name>(<quantified-class-name>...)] - Legacy Name:
<method-name>(<simple-class-name>...)
- Unique ID:
@ParameterizedTest- Unique ID:
[engine:<engine-name>][class:<quantified-class-name>]/[test-timplate:<method-name>(<quantified-class-name>...)]/[test-template-invocation:<parameter-set-number>] - Legacy Name:
<method-name>(<simple-class-name>...)[<parameter-set-number>]
- Unique ID:
For reference:
- quantified-class-name:
package-name+.+class-name+ ($+inner-class-name) - simple-class-name:
class-nameorinner-class-name
- Potential name conflicts:
@ParameterizedTest test(String)vs@ParameterizedTest test(Integer)- Two tests with the same name, but different parameterized arguments, is valid and may exist somewhere in someone's test code
- How do we differentiate the tests if we are using
DiscoverySelectors.selectMethod(class-name, method-name)? - Same name but different argument types
- Legacy Name uses simple names, meaning the packages of those classes are not given.
- Simple
@Testmethods don't have arguments so its typically<method-name>()so this isn't a problem for@Test - Templated tests using
@ParameterizedTestdo have arguments, so resolving the simple name to a fully quantified one becomes a problem.
- Simple
- Migrating from using
DiscoverySelectors.selectMethodtoDiscoverySelectors.selectUniqueId- Resolves the problems noted above
- Simplifies our code since we do not need to parse
TestIdentifierin order to select which tests to rerun while keeping the same behavior - Does not require new code coverage tests since no new control flow blocks are created (Unit tests and integration tests exist for this feature)
static class TestClass7 {
static List<Object[]> params() {
return Arrays.asList(
new Object[] { "Always pass", true },
new Object[] { "Always fail", false } );
}
@ParameterizedTest
@MethodSource("params")
void testParameterizedTestCases(String testName, boolean value) {
assertTrue( value );
}
}The second array { "Always fail", false } is what will be re-run so the ID looks like:
UniqueID - testParameterizedTestCases(params[1]): [engine:junit-jupiter]/[class:org.apache.maven.surefire.junitplatform.JUnitPlatformProviderTest$TestClass7]/[test-template:testParameterizedTestCases(java.lang.String, boolean)]/[test-template-invocation:#2]
If it were the first array that used false then it would end with [test-template-invocation:#1]
static class TestClass4 {
static int count;
@DisplayName( "Always passes" )
@Test
void testPass() {}
@Test
void testAborted() {
assumeFalse( true );
throw new IllegalStateException( "this exception should never happen" );
}
@Test
void testAlwaysError() {
throw new Error( "some error" );
}
@Test
void testAlwaysFail() {
assertTrue( false );
}
@Test
@Disabled
void testAlwaysSkipped() {
throw new IllegalStateException( "this test should be never called" );
}
@DisplayName( "Fails twice" )
@Test
void testFailTwice() {
count += 1;
assertTrue( count >= 3 );
}
}The following are the ID's of failing tests:
UniqueID - testAlwaysFail(): [engine:junit-jupiter]/[class:org.apache.maven.surefire.junitplatform.JUnitPlatformProviderTest$TestClass4]/[method:testAlwaysFail()]
UniqueID - testFailTwice(): [engine:junit-jupiter]/[class:org.apache.maven.surefire.junitplatform.JUnitPlatformProviderTest$TestClass4]/[method:testFailTwice()]
UniqueID - testAlwaysError(): [engine:junit-jupiter]/[class:org.apache.maven.surefire.junitplatform.JUnitPlatformProviderTest$TestClass4]/[method:testAlwaysError()]