Skip to content

OpenHFT/Chronicle-Test-Framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chronicle Test Framework

badge javadoc GitHub release%20notes subscribe brightgreen measure?project=OpenHFT ChronicleTestFramework&metric=alert status

About

This library provides support classes for writing JUnit tests. It supports both Junit4 and JUnit5.

Permutations

Permutaions work like this:

@Test
void print() {
    Permutation.of("A", "B", "C")
            .forEach(System.out::println);
}

This will produce the following output:

[A, B, C]
[A, C, B]
[B, A, C]
[B, C, A]
[C, A, B]
[C, B, A]

Testing using permutations:

@TestFactory
// Exhaustively tests that the order of setter invocation does not matter
Stream<DynamicTest> demo() {
    // Operations
    final Consumer<MyBean> setA = myBean -> myBean.setA(1);
    final Consumer<MyBean> setB = myBean -> myBean.setB(2);
    final Consumer<MyBean> setC = myBean -> myBean.setC(3);
    final MyBean expected = new MyBean(1, 2, 3);
    // DynamicTests
    return DynamicTest.stream(Permutation.of(setA, setB, setC),
            Objects::toString,
            operations -> {
                final MyBean actual = new MyBean();
                operations.forEach(oper -> oper.accept(actual));
                assertEquals(expected, actual);
            });
}

Combinations

Combinations work like this:

@Test
void print() {
    Combination.of("A", "B", "C")
            .forEach(System.out::println);
}

This will produce the following output:

[]
[A]
[B]
[C]
[A, B]
[A, C]
[B, C]
[A, B, C]

Testing using combinations:

@TestFactory
// Try all combinations of cosmic ray interference
    @TestFactory
        // Try all combinations of the Robot state machine
    Stream<DynamicTest> demo() {
        return DynamicTest.stream(Combination.<Consumer<FaultTolerantBitSet>>of(
                        FaultTolerantBitSet::cosmicRayBit3,
                        FaultTolerantBitSet::cosmicRayBit23,
                        FaultTolerantBitSet::cosmicRayBit13),
                Objects::toString,
                operations -> {
                    final FaultTolerantBitSet bitSet = new FaultTolerantBitSet();
                    operations.forEach(oper -> oper.accept(bitSet));
                    assertTrue(bitSet.isValid());
                });
    }

Combinations and Permutations

Combinations and Permutaions can be combined to create powerful exhaustive test vectors:

    @Test
    void demo() {
        Combination.of("A", "B", "C")
                .flatMap(Permutation::of)
                .forEach(System.out::println);
    }

This will produce the following output:

[A]
[B]
[C]
[A, B]
[B, A]
[A, C]
[C, A]
[B, C]
[C, B]
[A, B, C]
[A, C, B]
[B, A, C]
[B, C, A]
[C, A, B]
[C, B, A]

Products

Products are equivalent to nested loops but are easier to convert to a Stream of DynamicTest objects:

    @Test
    void print() {
        Product.of(Arrays.asList("A", "B", "C"), Arrays.asList(1, 2, 3))
                .forEach(System.out::println);
    }

This will produce the following output:

Product2Impl{first=A, second=1}
Product2Impl{first=A, second=2}
Product2Impl{first=A, second=3}
Product2Impl{first=B, second=1}
Product2Impl{first=B, second=2}
Product2Impl{first=B, second=3}
Product2Impl{first=C, second=1}
Product2Impl{first=C, second=2}
Product2Impl{first=C, second=3}

Products can use built-in tuples like Product2Impl or we can provide custom constructors to use our own.

Testing using combinations:

@TestFactory
// Exhaustively tests if various empty collections invariants holds
Stream<DynamicTest> demo() {
    // Operations
    final List<Collection<Integer>> collections = Arrays.asList(new LinkedList<>(), new ArrayList<>(), new HashSet<>());
    // Operations
    final Consumer<Collection<Integer>> empty =
            c -> assertTrue(c.isEmpty(), c.getClass() + ".empty() was false");
    final Consumer<Collection<Integer>> size =
            c -> assertEquals(0, c.size(), c.getClass() + ".size() != 0");
    final Consumer<Collection<Integer>> streamCount =
            c -> assertEquals(0, c.stream().count(), c.getClass() + ".stream().count() != 0");
    final List<Consumer<Collection<Integer>>> operations = Arrays.asList(empty, size, streamCount);

            // DynamicTests
    return DynamicTest.stream(Product.of(collections, operations),
            Objects::toString,
            tuple -> {
                tuple.second().accept(tuple.first());
            });
}