I've used a common approach for property-based matrix testing in Java. Using JUnit's ParameterizedTest and a MethodSource annotations to point to a method as an argument supplier that spits out a stream representing a matrix.
It's pretty straightforward, but the more parameter types we have in our matrix, the harder it is to read or write the method supplying them. 😵
Let's take a look.
First, these are the two types for our matrix, these should spit out 6 test cases:
enum Direction {
INCOMING,
OUTGOING
}
enum Status {
SUCCESS,
FAILURE,
WAITING
}
Implementing a matrix from these Enums with JUnit's ParameterizedTest and a MethodSource:
@ParameterizedTest
@MethodSource("getArguments")
void using_junit_parameterized_test_with_method_source(
final Direction direction, final Status status) {
assertTrue(true);
}
static Stream<Arguments> getArguments() {
return Stream.of(Direction.values())
.flatMap(d -> Stream.of(Status.values()).map(s -> arguments(d, s)));
}
Adding members to the existing Enums will dynamically increase the matrix and, therefore, the number of tests performed; there's no need to modify the test code.
But, adding a third type to the matrix and the getArguments
method will start losing its readability.
Lately, I discovered JUnit Pioneer, which is a JUnit 5 Extension Pack. Using its CartesianProductTest and CartesianEnumSource annotations, we can implement the same matrix simply and elegantly: 😃
@CartesianProductTest
@CartesianEnumSource(Direction.class)
@CartesianEnumSource(Status.class)
void using_junit_pioneer_cartesian_product_test_with_enum_source(
final Direction direction, final Status status) {
assertTrue(true);
}
This will spit out the same matrix, only now, adding a third element is quite simple: add another CartesianEnumSource annotation.
You can find other types of sources beside Enums, in JUnit Pioneer's Documentation.
As demonstrated in this repository, executing both matrix tests will print out:
[INFO] '-- JUnit Jupiter [OK]
[INFO] '-- Property Based Matrix Test [OK]
[INFO] +-- using junit pioneer cartesian product test with enum source (Direction, Status) [OK]
[INFO] | +-- [1] INCOMING, SUCCESS [OK]
[INFO] | +-- [2] INCOMING, FAILURE [OK]
[INFO] | +-- [3] INCOMING, WAITING [OK]
[INFO] | +-- [4] OUTGOING, SUCCESS [OK]
[INFO] | +-- [5] OUTGOING, FAILURE [OK]
[INFO] | '-- [6] OUTGOING, WAITING [OK]
[INFO] '-- using junit parameterized test with method source (Direction, Status) [OK]
[INFO] +-- [1] INCOMING, SUCCESS [OK]
[INFO] +-- [2] INCOMING, FAILURE [OK]
[INFO] +-- [3] INCOMING, WAITING [OK]
[INFO] +-- [4] OUTGOING, SUCCESS [OK]
[INFO] +-- [5] OUTGOING, FAILURE [OK]
[INFO] '-- [6] OUTGOING, WAITING [OK]
Check out the code for this tutorial in Github.
Top comments (0)