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.
<dependency>
<groupId>de.cuioss.test</groupId>
<artifactId>cui-test-generator</artifactId>
</dependency>
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 tode.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
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.
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;
}
}
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());
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());
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'
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());
}