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 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 {

    public void testCreateTodo(@ForAll String anyStr) { // <2>
        Todo todo = new Todo();

        todo.setTitle(anyStr); // <3>

        assertThat(todo.getTitle()).isNotNull(); // <4>

<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.

Adding a bit of complexity
@PropertyDefaults(tries = 10)
public class TodoTest {
    private static final int FUTURE_TIME = 1741598467;

    public void testCreateTodoWithDate(@ForAll String anyStr,
                                       @ForAll @IntRange(min = TodoTest.FUTURE_TIME) int unixtime) // <1>
        Todo todo = new Todo();


        DueDate dueDate = new DueDate();

        dueDate.setDue(Instant.ofEpochMilli(unixtime * 1000L) // <2>


        /* Arbitrary and contrived test <3> */
        Condition<Todo> cond1 = new Condition<>(t ->
                "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..


During my tests I’ve found some interesting bug, 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: