Skip to content

Support text blocks in @ValueSource and deprecate textBlock attribute in @CsvSource #5017

@manoelcampos

Description

@manoelcampos

Introduction

JUnit 6 requires JDK 17 and text blocks are already supported in @CsvSource(textBlock = ...). However, we need to explicitly choose between using a text block or a regular string.

JEP 378 aimed for the interchangeability of regular Strings and Text Blocks, but that textBlock attribute in @CsvSource() forces users to choose between them.

@CsvSource

The code snippet below shows that we need to use textBlock property to pass a multiline String and the test is run 3 times:

@ParameterizedTest
@CsvSource(textBlock =
        """
        2,1
        6,3
        10,5
        """)
void csvSourceTextBlock(int a, int b) {
    assertEquals(a, b*2);
}

But using the value default property, only the first line is parsed:

@ParameterizedTest
@CsvSource(
        """
        100,50
        200,100
        300,150
        """)
void csvSourceTextBlockUsingValueProp(int a, int b) {
    assertEquals(a, b*2);
}

@ValueSource

This other annotation doesn’t even allow using text blocks as one would expect. Despite using a text block the code compiles, it doesn't give the expected result:

@ParameterizedTest
@ValueSource(strings =
        """
        L1
        L2
        L3
        """)
void valueSourceTextBlock(final String value) {
    assertFalse(value.contains("\n"), "Each value must represent a single line only (without line break)");
}

Instead of running the test 3 times (one line at a time), it runs a single time with value "L1 L2 L3".

Motivation

Leveraging the utilization of text blocks and providing and more natural way to use them interchangeably with regular Strings will make tests easier and cleaner.

This code below:

@ValueSource(
        """
        One
        Two
        Three
        """
)

is much cleaner than:

@ValueSource(strings = {
        "One",
        "Two",
        "Three"
})

Proposal

Proposal for @ValueSource

Add a String value default property and leave the strings for backward compatibility and for users that prefer passing values as an array. Internally, if the value has a line break, split it and run as if a String array was given to the strings property.

Proposal for @CsvSource

  • Make the annotation split the value property at line breaks and run the test once for each resulting line.
  • Deprecate the textBlock property

Final Thoughts

Behaviour change may cause issues depending on the user provided strings (such as strings with an explicit \n), but that requires some tests. I don't know what the effort would be to implement these changes. However, if you think these are valuable enhancements, I'll be happy to try implementing them.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions