JUnit Jupiter extension for parameterized tests
—
The fundamental annotation and configuration for creating parameterized tests in JUnit Jupiter.
The primary annotation that marks a test method as parameterized, enabling multiple invocations with different argument sets.
/**
* Marks a test method as parameterized, enabling execution with multiple argument sets
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@API(status = STABLE, since = "5.0")
@TestTemplate
@ExtendWith(ParameterizedTestExtension.class)
@interface ParameterizedTest {
/**
* Custom display name pattern for test invocations.
* Supports placeholders: {displayName}, {index}, {arguments}, {argumentsWithNames},
* {argumentSetName}, {argumentSetNameOrArgumentsWithNames}
*/
String name() default "[{index}] {argumentSetNameOrArgumentsWithNames}";
/**
* Whether to automatically close AutoCloseable arguments after test execution
*/
boolean autoCloseArguments() default true;
/**
* Whether to allow test execution when no argument sources provide arguments
*/
boolean allowZeroInvocations() default false;
/**
* Controls how argument count is validated against parameter count
*/
ArgumentCountValidationMode argumentCountValidation() default DEFAULT;
}Usage Examples:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class CoreTestingExample {
// Basic parameterized test
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void testWithDefaultName(int value) {
assertTrue(value > 0);
}
// Custom display name
@ParameterizedTest(name = "Testing with value: {0}")
@ValueSource(strings = {"apple", "banana"})
void testWithCustomName(String fruit) {
assertNotNull(fruit);
}
// Custom display name with placeholders
@ParameterizedTest(name = "[{index}] {displayName} - input: {arguments}")
@ValueSource(doubles = {1.5, 2.5, 3.5})
void testWithDetailedName(double value) {
assertTrue(value > 1.0);
}
}Controls how the framework validates the number of arguments provided against the number of test method parameters.
/**
* Validation mode for argument count vs parameter count
*/
@API(status = EXPERIMENTAL, since = "5.12")
enum ArgumentCountValidationMode {
/**
* Default validation behavior - typically strict validation
*/
DEFAULT,
/**
* No argument count validation performed
*/
NONE,
/**
* Strict validation - argument count must exactly match parameter count
*/
STRICT
}Usage Examples:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.ArgumentCountValidationMode;
import org.junit.jupiter.params.provider.CsvSource;
class ValidationModeExample {
// Strict validation (default behavior)
@ParameterizedTest
@CsvSource({"1,apple", "2,banana"})
void testStrictValidation(int id, String name) {
// Must have exactly 2 arguments for 2 parameters
}
// No validation - allows mismatched argument counts
@ParameterizedTest(argumentCountValidation = ArgumentCountValidationMode.NONE)
@CsvSource({"1,apple,extra", "2,banana"}) // Mixed argument counts
void testNoValidation(int id, String name) {
// Accepts varying argument counts
}
// Explicit strict validation
@ParameterizedTest(argumentCountValidation = ArgumentCountValidationMode.STRICT)
@CsvSource({"1,apple", "2,banana"})
void testExplicitStrictValidation(int id, String name) {
// Enforces exact argument count match
}
}The name attribute supports several placeholder patterns for customizing test display names:
{displayName} - The display name of the test method{index} - The current invocation index (1-based){arguments} - Complete argument list as comma-separated string{argumentsWithNames} - Arguments with parameter names if available{0}, {1}, ... - Individual arguments by indexDisplay Name Examples:
class DisplayNameExamples {
@ParameterizedTest(name = "Test #{index}: {displayName}")
@ValueSource(ints = {1, 2, 3})
void basicCounter(int value) { }
// Displays: "Test #1: basicCounter", "Test #2: basicCounter", etc.
@ParameterizedTest(name = "Value {0} should be positive")
@ValueSource(ints = {1, 2, 3})
void positiveNumbers(int value) { }
// Displays: "Value 1 should be positive", "Value 2 should be positive", etc.
@ParameterizedTest(name = "Processing: {arguments}")
@CsvSource({"apple,red", "banana,yellow"})
void colorMapping(String fruit, String color) { }
// Displays: "Processing: apple, red", "Processing: banana, yellow"
}When autoCloseArguments = true (default), the framework automatically closes any AutoCloseable arguments after test execution:
class ResourceManagementExample {
@ParameterizedTest
@MethodSource("provideStreams")
void testWithAutoClose(InputStream stream) {
// Stream automatically closed after test execution
assertNotNull(stream);
}
@ParameterizedTest(autoCloseArguments = false)
@MethodSource("provideStreams")
void testWithoutAutoClose(InputStream stream) {
// Must manually close stream if needed
try (stream) {
assertNotNull(stream);
}
}
static Stream<InputStream> provideStreams() {
return Stream.of(
new ByteArrayInputStream("test1".getBytes()),
new ByteArrayInputStream("test2".getBytes())
);
}
}This feature ensures proper resource cleanup and prevents resource leaks in parameterized tests that work with files, streams, database connections, or other closeable resources.
Install with Tessl CLI
npx tessl i tessl/maven-org-junit-jupiter--junit-jupiter-params