Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating display names for @ParameterizedTest in JUnit 5

I have a bunch of @ParameterizedTests that receive parameters from a @MethodSource with quite verbose toString() results (e.g. Selenium's WebDriver). These are used per default to compose the corresponding display names. From the JUnit 5 user guide:

By default, the display name of a parameterized test invocation contains the invocation index and the String representation of all arguments for that specific invocation. However, you can customize invocation display names via the name attribute of the @ParameterizedTest annotation […]

While this allows customizing the display names to a certain degree, it seems like I cannot adapt the string representation of the individual parameters. Unfortunately, specifying a generator via @DisplayNameGeneration can only be applied at the class level and doesn't affect the display name of the parameterized test invocations.

Is there a way to use a DisplayNameGenerator for @ParameterizedTest or to customize the string representation of the given parameters?

like image 302
beatngu13 Avatar asked Sep 11 '19 16:09

beatngu13


People also ask

How do you create a parameterized test case?

There are five steps that you need to follow to create a parameterized test. Annotate test class with @RunWith(Parameterized. class). Create a public static method annotated with @Parameters that returns a Collection of Objects (as Array) as test data set.

What is parameterized test in JUnit 5?

JUnit 5, the next generation of JUnit, facilitates writing developer tests with shiny new features. One such feature is parameterized tests. This feature enables us to execute a single test method multiple times with different parameters.

Which option represents a source for parameterized tests in JUnit 5?

@ValueSource. Use @ValueSource for simple literal values such as primitives and strings. It specifies a single array of values and can only be used for providing a single argument per parameterized test invocation. Java supports autoboxing so we can consume the literals in their wrapper classes as well.


3 Answers

To indirectly achieve your goal until this is directly supported by JUnit, one can always add an argument to the test that's the desired string. The customization then needs to be done in the argument provider method.

@ParameterizedTest(name = "{index} {1}")
@MethodSource("argumentProvider")
public void testSomething(Object someObject, String niceRepresentation) {
    // Test something
}

private static Stream<Arguments> argumentProvider() {
    return Stream.of(
            Arguments.of(new Object(), "Nice 1"),
            Arguments.of(new Object(), "Nice 2")
    );
}

The drawback is that the unit test is supplied arguments that are not used in the test's implementation, which can harm clarity, but then it becomes a trade-off with the verbose name in the test report.

like image 121
SDJ Avatar answered Oct 12 '22 01:10

SDJ


As of JUnit 5.8.0, there is a Named<T> interface as part of the JUnit Jupiter API with "automatic support for injecting the contained payload [the arguments] into parameterized methods directly" (see issue #2301). Example:

@DisplayName("A parameterized test with named arguments")
@ParameterizedTest
@MethodSource("namedArguments")
void testWithNamedArguments(File file) {}

static Stream<Arguments> namedArguments() {
    return Stream.of(
        Arguments.of(Named.of("An important file", new File("path1"))),
        Arguments.of(Named.of("Another file", new File("path2")))
    );
}

If you prefer static imports, you can also go for the corresponding aliases from Arguments and Named:

arguments(named("An important file", new File("path1")))

For more information, please refer to the corresponding docs.

like image 48
beatngu13 Avatar answered Oct 12 '22 03:10

beatngu13


just adding a similar problem with surefire reports.

Wasn't getting the correct test name in the reports after using @DisplayName and @ParameterizedTest(name = "{0}").

This issue solved my problem #1255

       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M4</version>
            <configuration>
                <statelessTestsetReporter
                        implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
                    <disable>false</disable>
                    <version>3.0</version>
                    <usePhrasedFileName>false</usePhrasedFileName>
                    <usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
                    <usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
                    <usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
                </statelessTestsetReporter>
            </configuration>
        </plugin>
like image 1
Corgan Avatar answered Oct 12 '22 01:10

Corgan