JUnit Jupiter extension for parameterized tests
npx @tessl/cli install tessl/maven-org-junit-jupiter--junit-jupiter-params@5.12.0JUnit Jupiter Params provides a comprehensive parameterized testing extension for JUnit 5, enabling developers to run the same test method multiple times with different input parameters. It offers a rich set of argument providers, automatic type conversion, and argument aggregation capabilities to significantly reduce code duplication and improve test coverage.
implementation 'org.junit.jupiter:junit-jupiter-params:5.12.2' (Gradle) or <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.12.2</version></dependency> (Maven)import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.provider.CsvSource;
class ParameterizedTestExamples {
@ParameterizedTest
@ValueSource(strings = {"apple", "banana", "cherry"})
void testWithStringValues(String fruit) {
assertNotNull(fruit);
assertTrue(fruit.length() > 3);
}
@ParameterizedTest
@CsvSource({
"1, apple, true",
"2, banana, false",
"3, cherry, true"
})
void testWithCsvSource(int id, String name, boolean active) {
assertTrue(id > 0);
assertNotNull(name);
}
}JUnit Jupiter Params is built around several key components:
@ParameterizedTest marks test methods for parameterized executionThe fundamental annotation for creating parameterized tests with customizable display names and validation modes.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface ParameterizedTest {
String name() default "[{index}] {argumentSetNameOrArgumentsWithNames}";
boolean autoCloseArguments() default true;
boolean allowZeroInvocations() default false;
ArgumentCountValidationMode argumentCountValidation() default DEFAULT;
}
enum ArgumentCountValidationMode {
DEFAULT, NONE, STRICT
}Simple argument providers for literal values, null values, and empty collections.
@interface ValueSource {
short[] shorts() default {};
byte[] bytes() default {};
int[] ints() default {};
long[] longs() default {};
float[] floats() default {};
double[] doubles() default {};
char[] chars() default {};
boolean[] booleans() default {};
String[] strings() default {};
Class<?>[] classes() default {};
}
@interface NullSource { }
@interface EmptySource { }
@interface NullAndEmptySource { }Comprehensive CSV data support for inline data and external files with extensive parsing customization.
@interface CsvSource {
String[] value() default {};
String textBlock() default "";
boolean useHeadersInDisplayName() default false;
char quoteCharacter() default '\'';
char delimiter() default ',';
String delimiterString() default "";
String emptyValue() default "";
String[] nullValues() default "";
int maxCharsPerColumn() default 4096;
boolean ignoreLeadingAndTrailingWhitespace() default true;
}
@interface CsvFileSource {
String[] resources() default {};
String[] files() default {};
String encoding() default "UTF-8";
String lineSeparator() default "\n";
int numLinesToSkip() default 0;
// ... plus all CsvSource parsing attributes
}Advanced argument providers for enum constants and method-generated arguments.
@interface EnumSource {
Class<? extends Enum<?>> value() default Enum.class;
String[] names() default {};
Mode mode() default INCLUDE;
enum Mode {
INCLUDE, EXCLUDE, MATCH_ALL, MATCH_ANY, MATCH_NONE
}
}
@interface MethodSource {
String[] value() default "";
}
@interface FieldSource {
String[] value() default "";
}Extension points for custom argument providers and the fundamental interfaces.
@interface ArgumentsSource {
Class<? extends ArgumentsProvider> value();
}
interface ArgumentsProvider {
Stream<? extends Arguments> provideArguments(ExtensionContext context)
throws Exception;
}
interface Arguments {
Object[] get();
static Arguments of(Object... arguments) { /* ... */ }
static Arguments arguments(Object... arguments) { /* ... */ }
}Type conversion system with built-in converters and extension points for custom conversions.
@interface ConvertWith {
Class<? extends ArgumentConverter> value();
}
interface ArgumentConverter {
Object convert(Object source, ParameterContext context)
throws ArgumentConversionException;
}
abstract class SimpleArgumentConverter implements ArgumentConverter {
protected abstract Object convert(Object source, Class<?> targetType)
throws ArgumentConversionException;
}
abstract class TypedArgumentConverter<S, T> implements ArgumentConverter {
protected TypedArgumentConverter(Class<S> sourceType, Class<T> targetType) { }
protected abstract T convert(S source) throws ArgumentConversionException;
}System for combining multiple arguments into single parameter objects with type-safe access.
@interface AggregateWith {
Class<? extends ArgumentsAggregator> value();
}
interface ArgumentsAccessor {
Object get(int index);
<T> T get(int index, Class<T> requiredType);
// Typed getters
Character getCharacter(int index);
Boolean getBoolean(int index);
Byte getByte(int index);
Short getShort(int index);
Integer getInteger(int index);
Long getLong(int index);
Float getFloat(int index);
Double getDouble(int index);
String getString(int index);
int size();
Object[] toArray();
List<Object> toList();
}
interface ArgumentsAggregator {
Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context)
throws ArgumentsAggregationException;
}class ArgumentConversionException extends JUnitException { }
class ArgumentsAggregationException extends JUnitException { }
class ArgumentAccessException extends JUnitException { }
class CsvParsingException extends JUnitException { }These exceptions provide detailed error information when argument processing fails, helping developers debug parameterized test issues effectively.