If you wrote unit tests with JUnit 4, a notable pain point was the lack of first-class parameter support in test methods, leading to extensive boilerplate duplication when validating multiple inputs :-1:. While TestNG addressed this earlier, JUnit 5 introduced native Parameterized Tests to solve this elegantly :heart:.

Required Setup
To use Parameterized Tests, add the junit-jupiter-params dependency.
With Gradle:
| |
With Maven:
| |
Argument Sources
Arguments for Parameterized Tests can be provided using various Argument Sources:
@ValueSource
The simplest way to supply literal test inputs. @ValueSource supports the following literal types:
- short
- byte
- int
- long
- float
- double
- char
- boolean
- java.lang.String
- java.lang.Class
The following example tests String.isNullOrBlank against 6 test inputs listed in @ValueSource:
| |
To test null and empty strings explicitly, you can also use @NullSource and @EmptySource (or the combined @NullAndEmptySource).
@EnumSource
Supplies constants from an enum. By default, it passes all enum constants. To test a specific subset, specify the constant names as shown below.
For example, verifying that April, June, September, and November each have 30 days:
| |
@MethodSource
While @ValueSource and @EnumSource work well for simple literals, complex test objects require a factory method. Note that the factory method must be @JvmStatic in Kotlin / static in Java.
Here is an optimized version of the test from Use Mock to make Unit Test easy consolidated into a single parameterized test method:
| |
with the data supplied by:
| |
Note: The factory method typically returns a Stream of Arguments. However, JUnit 5 also supports:
DoubleStream,LongStream,IntStreamCollectionIterator,Iterable- Array of objects or primitives
@CsvSource
Supplies tabular test arguments as comma-separated values.
Testing String.toUpperCase:
| |
@CsvFileSource
Similar to @CsvSource, but loads test data directly from an external CSV resource file.
| |
with trim.csv:
str,expected
trile,TRILE
tRilE,TRILE
trILE,TRILE
@ArgumentsSource
Provides test arguments via a custom implementation class of ArgumentsProvider rather than an inline factory method:
| |
| |
Customizing Display Names
By default, parameterized test reports can sometimes be difficult to read in CI dashboards:
| |
Yields default names:
| Test | Method name | Duration | Result |
|---|---|---|---|
| [1] month=APRIL | test month have 30 day(Month)[1] | 0.033s | passed |
| [2] month=JUNE | test month have 30 day(Month)[2] | 0.001s | passed |
| [3] month=SEPTEMBER | test month have 30 day(Month)[3] | 0.001s | passed |
| [4] month=NOVEMBER | test month have 30 day(Month)[4] | 0.001s | passed |
You can customize the display template using the name attribute:
| |
Now the test reports display cleanly:
| Test | Method name | Duration | Result |
|---|---|---|---|
| #1 - [APRIL] have 30 day | test month have 30 day(Month)[1] | 0.034s | passed |
| #2 - [JUNE] have 30 day | test month have 30 day(Month)[2] | 0.001s | passed |
| #3 - [SEPTEMBER] have 30 day | test month have 30 day(Month)[3] | 0.001s | passed |
| #4 - [NOVEMBER] have 30 day | test month have 30 day(Month)[4] | 0.001s | passed |
Placeholders available in name:
{index}: The current invocation index (1-based).{arguments}: The complete list of arguments.{0},{1}, …: Individual argument values by 0-based index.