Junit5: Include parameter names in default name of @ParameterizedTest

Created on 4 Oct 2019  路  12Comments  路  Source: junit-team/junit5

Suppose I have a test:

    @ParameterizedTest
    @MethodSource("implementationsAndIps")
    public void test(String httpImplementation, String targetHost, InetAddress sourceIp,
                     WireMockServer server, JMeterVariables vars) throws SocketException {

The result looks unreadable:

[3] HttpClient4, 127.0.0.1, /127.0.0.1
[1] HttpClient4, 127.0.0.1, /fe80:0:0:0:0:0:0:1%lo0
[7] Java, 127.0.0.1, /fe80:0:0:0:0:0:0:1%lo0
[4] HttpClient4, [::1], /fe80:0:0:0:0:0:0:1%lo0
[5] HttpClient4, [::1], /0:0:0:0:0:0:0:1%lo0
[8] Java, 127.0.0.1, /0:0:0:0:0:0:0:1%lo0
[10] Java, [::1], /fe80:0:0:0:0:0:0:1%lo0

It does not really help if the test fails.
That means every time I use @ParameterizedTest I have to declare test name explicitly.
That is sad.

What if JUnit generated something like

[3] httpImplementation=HttpClient4, targetHost=127.0.0.1, sourceIp=/127.0.0.1
[1] httpImplementation=HttpClient4, targetHost=127.0.0.1, sourceIp=/fe80:0:0:0:0:0:0:1%lo0
...

?

It would make lots of tests and test failures easier to understand.
I'm OK if it is {arguments_with_names}. Then I could create @ParameterizedTestWithArgNames annotation that uses detailed name.

PS. I've seen https://github.com/junit-team/junit5/issues/1154, however, I don't really want to deal and/or declare resolvers.

Jupiter parameterized tests enhancement

Most helpful comment

Indeed. Better to stay consistent and go with camel case there. Good catch.

All 12 comments

Tentatively slated for 5.6 M1 solely for the purpose of _team discussion_ and triaging.

FYI: this would need to be an opt-in feature. In addition, parameter names are not always present in the compiled byte code. To include them in the byte code, the test code must be compiled with the -parameters compiler flag.

You assume I use Java, however, Kotlin does retain parameter names always 馃槈

@sbrannen Could we check whether parameter names are present and include them only if so?

@sbrannen Could we check whether parameter names are present and include them only if so?

Yes. See java.lang.reflect.Parameter.isNamePresent().

Team Decision: Introduce new {arguments_with_names} pattern and make it the default. Only include parameter names if present in bytecode and parameter types are known (e.g. not for ArgumentsAccessor and ArgumentsAggregator).

@vlsi Would you be interested in submitting a PR for this?

FYI, just started working on it.

Only include parameter names if present in bytecode and parameter types are known (e.g. not for ArgumentsAccessor and ArgumentsAggregator).

@junit-team/junit-lambda If one of these conditions are encountered for one of the parameters, do we fallback on the current behavior for all of them or do we still add names for the other parameters? (I'd rather fallback on the {arguments} pattern)

I think we could support the case of mixed position and accessor/aggregator arguments, i.e. for test like the following:

@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int value, ArgumentsAccessor accessor) {
    assertTrue(value > 0 && value < 4);
}

The display names currently are [1] 1 etc. so we could make them [1] value=1 etc.

We should be able to extract the logic in ParameterizedTestParameterResolver, i.e. only add the parameter name if the parameter index is < methodContext.indexOfFirstAggregator() (if methodContext.hasAggregator()).

I'm wondering if we should call the pattern {arguments_with_names} or {argumentsWithNames}?
I just noticed that the existing {displayName} pattern is in camel case...

Indeed. Better to stay consistent and go with camel case there. Good catch.

Was this page helpful?
0 / 5 - 0 ratings