Skip to content

cuioss/cui-test-generator

cui-test-generator

What is it?

Using the generators help creating variations of test-data. On the one hand it produces a large number of different values. On the other hand it makes error cases reproducible see de.cuioss.test.generator.junit.EnableGeneratorController and de.cuioss.test.generator.junit.GeneratorSeed for details.

Maven Coordinates

    <dependency>
        <groupId>de.cuioss.test</groupId>
        <artifactId>cui-test-generator</artifactId>
    </dependency>

Provided Features

The generators defined within this packages are the base for the cui-value-object test framework. In essence, it is a variant of QuickCheck. In the current implementation it actually uses code derived from QuickCheck, thanks guys, but mostly the generator part. This code is isolated in de.cuioss.test.generator.internal.net.java.quickcheck and will be replaced in the future.

Therefore: Do not use any of that code at all! Central elements are:

  • de.cuioss.test.generator.TypedGenerator: Is the core type. Instances of it are used for generating arbitrary instances of any value-object. Compared to de.cuioss.test.generator.internal.net.java.quickcheck.Generator it provides an additional method providing runtime information on the type being generated: de.cuioss.test.generator.TypedGenerator.getType().

  • de.cuioss.test.generator.Generators: Factory methods for accessing de.cuioss.test.generator.TypedGenerator for many java-lang types.

  • de.cuioss.test.generator.domain: Provides some domain specific de.cuioss.test.generator.TypedGenerator

Usage

The usage is straight forward TypedGenerator#next() always returns a random object that can be used for testing. See section 'Generators' on samples for concrete generators.

TypedGenerator

de.cuioss.test.generator.TypedGenerator

Central interface for a concrete generator instance. TypedGenerator#next() provides a random instance, TypedGenerator#getType() provides the types. Sample implementation:

public class ZoneOffsetGenerator implements TypedGenerator<ZoneOffset> {

    private static final TypedGenerator<ZoneId> ZONE_IDS_GEN =
        Generators.fixedValues(ZoneId.class, getAvailableZoneIds().stream().map(ZoneId::of).collect(toList()));

    @Override
    public java.time.ZoneOffset next() {
        return LocalDateTime.now().atZone(ZONE_IDS_GEN.next()).getOffset();
    }

    @Override
    public Class<ZoneOffset> getType() {
        return ZoneOffset.class;
    }

}

Generators

de.cuioss.test.generator.Generators

Central factory for TypedGenerator for most java-built-in types and wrappers for fixedValue and enumValue variants

 assertNotNull(Generators.strings().next());
 assertNotNull(Generators.letterStrings().next());
 assertFalse(isEmpty(Generators.nonEmptyStrings().next()));
 assertFalse(isEmpty(Generators.letterStrings(1, 2).next()));

 assertNotNull(Generators.booleans().next());
 assertNotNull(Generators.localTimes().next());
 assertNotNull(Generators.fixedValues(String.class, "https://cuioss.de", "https://www.heise.de", "http://getbootstrap.com").next());

 assertEquals(Temporal.class, Generators.temporals().getType());
 assertNotNull(Generators.enumValues(PropertyMemberInfo.class).next());
 assertEquals(PropertyMemberInfo.class, Generators.enumValues(PropertyMemberInfo.class).getType());

CollectionGenerator

de.cuioss.test.generator.impl.CollectionGenerator<T>

Wraps a given TypedGenerator and provides additional methods for creating Lists and Sets

 CollectionGenerator<String> generator = new CollectionGenerator<>(Generators.nonEmptyStrings());
 assertNotNull(generator.list());
 assertNotNull(generator.set());

EnableGeneratorController

de.cuioss.test.generator.junit.EnableGeneratorController

This annotation is meant to be set on a junit 5 test-case. It controls the generator subsystem and, in case of test-failures, provides information, that can be used for repeating the failed tests with a fixed seed for the generators, see de.cuioss.test.generator.junit.GeneratorSeed for details. This fixed seed results in the generators reproducing the exact same test-data.

Sample output:

GeneratorController seed was 4711L.
Use a fixed seed by applying @GeneratorSeed(4711L) for the method/class,
or by using the system property '-Dio.cui.test.generator.seed=4711'

GeneratorSeed

de.cuioss.test.generator.junit.GeneratorSeed

This annotation is to be used in the context of EnableGeneratorController. It explicitly sets the seed for the generators.

Usage:

@EnableGeneratorController
@GeneratorSeed(5L)
class GeneratorControllerExtensionTest {

    @Test
    @GeneratorSeed(11L)
    void shouldReadFromMethod() {
        assertEquals(11L, RandomConfiguration.getLastSeed());
    }

    @Test
    void shouldReadFromType() {
        assertEquals(5L, RandomConfiguration.getLastSeed());
    }