Property based testing
I initially read about the Python framework Hypothesis and I must say I like the overall idea to just define ranges and the framework does a dozen of tests with semi-random values.
This might lead to combinations, you normally wouldn’t think of.
So since there is a java version (jqwik) of it, let us look into the various generators that can be used.
First steps &
In general, the whole handling of pretty straight forward.
@PropertyDefaults(tries = 10) (1)
public class TodoTest {
@Property
public void testCreateTodo(@ForAll String anyStr) { (2)
Todo todo = new Todo();
todo.setTitle(anyStr); (3)
todo.setDescription(anyStr);
assertThat(todo.getTitle()).isNotNull(); (4)
assertThat(todo.getDescription()).isNotNull();
}
}
1 | This tells jqwik how often to run the test with different generator values. |
2 | Here @ForAll just marks the value that is taken from a generator. |
3 | The parameter anyStr can now be used like you’d expect. |
4 | And finally the tests can be done with your favorite assertion library. |
Adding a bit of complexity &
@PropertyDefaults(tries = 10)
public class TodoTest {
private static final int FUTURE_TIME = 1741598467;
@Property
public void testCreateTodoWithDate(@ForAll String anyStr,
@ForAll @IntRange(min = TodoTest.FUTURE_TIME) int unixtime) (1)
{
Todo todo = new Todo();
todo.setTitle(anyStr);
todo.setDescription(anyStr);
DueDate dueDate = new DueDate();
dueDate.setStart(LocalDate.now());
dueDate.setDue(Instant.ofEpochMilli(unixtime * 1000L) (2)
.atZone(ZoneId.systemDefault()).toLocalDate());
todo.setDueDate(dueDate);
/* Arbitrary and contrived test */
Condition<Todo> cond1 = new Condition<>(t -> (3)
t.getDueDate().getStart().isBefore(t.getDueDate().getDue()),
"Start date is before due date");
Condition<Todo> cond2 = new Condition<>(TodoBase::getDone,
"Todo must not be done");
assertThat(todo).is(allOf(cond1, cond2));
}
}
1 | This is pretty much the same, besides it includes an @IntRange now. |
2 | Here we use unixtime as an input to create dates. |
3 | A small test of test combinators.. |
Conclusion &
During my tests I’ve found some interesting bugs, mostly related to empty string and some weird combination of unicode characters. I think the handling is pretty easy and generators can be a huge help to avoid some kind of errors.
As usual, my showcase can be found here: