AutoParams is an arbitrary test data generator for parameterized tests in Java inspired by AutoFixture.
Sometimes setting all the test data manually is very annoying. Sometimes some test data is required but not that important for a particular test. AutoParams automatically generates test arguments for your parameterized test method so you can focus more on your domain and your requirements.
AutoParams is very easy to use. Just decorate your parameterized test method with @AutoSource
annotation just like using @ValueSource
annotation or @CsvSource
annotation. That's all. Then AutoParams wiil generate arbitrary arguments for the parameters of the test method automatically.
@ParameterizedTest
@AutoSource
void parameterizedTest(int a, int b) {
Calculator sut = new Calculator();
int actual = sut.add(a, b);
assertEquals(a + b, actual);
}
In the example above, you can see that the arbitrary test data may eliminate the need for triangulation from tests.
- JDK 1.8 or higher
<dependency>
<groupId>io.github.javaunit</groupId>
<artifactId>autoparams</artifactId>
<version>0.1.3</version>
</dependency>
testImplementation 'io.github.javaunit:autoparams:0.1.3'
AutoParams generates arbitrary test arguments of primitive types.
@ParameterizedTest
@AutoSource
void testMethod(boolean x1, int x2, long x3, float x4, double x5, char x6) {
}
AutoParams generates arbitrary simple objects for the test parameters.
@ParameterizedTest
@AutoSource
void testMethod(String x1, UUID x2, BigInteger x3) {
}
Enum types are also supported. AutoParams randomly selects enum values.
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
@ParameterizedTest
@AutoSource
void testMethod(Day day) {
}
AutoParams creates complex objects using a public constructor with arbitrary arguments. If the type has more than one public constructors, AutoParams chooses the constructor with the fewest parameters.
class ComplexObject {
private final int value1;
private final String value2;
public ComplexObject(int value1, String value2) {
this.value1 = value1;
this.value2 = value2;
}
public int getValue1() {
return value1;
}
public String getValue2() {
return value2;
}
}
@ParameterizedTest
@AutoSource
void testMethod(ComplexObject object) {
}
When AutoParams creates objects of complex types it follows the following rules.
- The constructor decorated with
@ConstructorProperties
annotation is preferentially selected. - AutoParams selects the constructor with the fewest parameters.
class ComplexObject {
private final int value1;
private final String value2;
private final UUID value3;
@ConstructorProperties({"value1", "value2, value3"})
public ComplexObject(int value1, String value2, UUID value3) {
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}
@ConstructorProperties({"value1", "value2"})
public ComplexObject(int value1, String value2) {
this(value1, value2, null);
}
public ComplexObject(int value1) {
this(value1, null, null);
}
public int getValue1() {
return value1;
}
public String getValue2() {
return value2;
}
public UUID getValue3() {
return value3;
}
}
@ParameterizedTest
@AutoSource
void testMethod(ComplexObject object) {
assertNotNull(object.getValue2());
assertNull(object.getValue3());
}
AutoParams creates objects of generic type using a public constructor with arbitrary arguments. If the type has more than one public constructors, AutoParams chooses the constructor with the fewest parameters.
class GenericObject<T1, T2> {
private final T1 value1;
private final T2 value2;
public GenericObject(T1 value1, T2 value2) {
this.value1 = value1;
this.value2 = value2;
}
public T1 getValue1() {
return value2;
}
public T2 getValue2() {
return value3;
}
}
@ParameterizedTest
@AutoSource
void testMethod(
GenericObject<String, ComplexObject> object1,
GenericObject<UUID, GenericObject<String, ComplexObject>> object2) {
}
AutoParams supports a variety of collection types.
AutoParams generates an array instance with three elements.
@ParameterizedTest
@AutoSource
void testMethod(int[] array1, String[] array2) {
}
List<E>
interface and ArrayList<E>
class supported. Generated list objects contain few elements.
@ParameterizedTest
@AutoSource
void testMethod(List<String> list, ArrayList<UUID> arrayList) {
}
Set<E>
interface and HashSet<E>
class supported. Generated set objects contain few elements.
@ParameterizedTest
@AutoSource
void testMethod(Set<String> set, HashSet<UUID> hashSet) {
}
Map<K, V>
interface and HashMap<K, V>
class supported. Generated map objects contain few pairs.
@ParameterizedTest
@AutoSource
void testMethod(Map<String, ComplexObject> map, HashMap<UUID, ComplexObject> hashMap) {
}
AutoParams supports the generic Stream<T>
interface. Generated stream objects provide few elements.
@ParameterizedTest
@AutoSource
void testMethod(Stream<ComplexObject> stream) {
}
Stream Interfaces specific to primitive types are supported.
@ParameterizedTest
@AutoSource
void testMethod(IntStream intStream, LongStream longStream, DoubleStream doubleStream) {
}
Unit tests can be repeated with arbitrary test data. Set repeat
property of @AutoSource
annotation as many times as you want to repeat.
@ParameterizedTest
@AutoSource(repeat = 10)
void testMethod(int a, int b) {
// This test method is performed ten times.
Calculator sut = new Calculator();
int actual = sut.add(a, b);
assertEquals(a + b, actual);
}
You can freeze the generated argument to the type with @Fixed
annotation. @AutoSource
reuses the argument of the parameter decorated with @Fixed
annotation for subsequent value generation.
class ValueContainer {
private final String value;
public ValueContainer(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@ParameterizedTest
@AutoSource
void testMethod(@Fixed String arg1, String arg2, ValueContainer arg3) {
assertEquals(arg1, arg2);
assertEquals(arg1, arg3.getValue());
}
@ValueAutoSource
annotation combines the functionalities of @ValueSource
and @AutoSource
. It assigns the provides value to the first parameter then generates arbitrary values for other parameters.
@ParameterizedTest
@ValueAutoSource(strings = {"foo"})
void testMethod(String arg1, String arg2) {
assertEquals("foo", arg1);
assertNotEquals(arg1, arg2);
}
@Fixed
annotation correctly works with @ValueAutoSource
.
class ValueContainer {
private final String value;
public ValueContainer(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@ParameterizedTest
@ValueAutoSource(strings = {"foo"})
void testMethod(@Fixed String arg1, String arg2, ValueContainer arg3) {
assertEquals("foo", arg2);
assertEquals("foo", arg3.getValue());
}
@CsvAutoSource
annotation combines the functionalities of @CsvSource
and @AutoSource
. You can specifiy arguments in CSV for the forepart parameters. The remaining parameters will be assigned with the arbitrary values.
@ParameterizedTest
@CsvAutoSource({"16, foo"})
void testMethod(int arg1, String arg2, UUID arg3) {
assertEquals(16, arg1);
assertNotEquals("foo", arg2);
}
@Fixed
annotation correctly works with @CsvAutoSource
.
class ValueContainer {
private final String value;
public ValueContainer(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@ParameterizedTest
@CsvAutoSource({"16, foo"})
void testMethod(int arg1, @Fixed String arg2, ValueContainer arg3) {
assertEquals("foo", arg3.getValue());
}