Java library to generate random data (numbers, strings, dates) - to facilitate Randomized Testing. Randomization may be used to improve coverage, but it can also speed up the process of writing & running tests. Some use cases for randomization:
- Combinatorial Testing - helps reducing the number of test cases you need to write and run
- Fighting with Unique Constraints - do you have a test that registers users with unique username? And the next time you run the test it fails because such user already exists..
- "Wow, I didn't know about that" effect - sometimes randomization may discover tricky cases that you couldn't think of.
- Which one to pick? - often when choosing test data there is no clear winner of what value to pick. Randomization helps with that and ensures we're not prone to Pesticides Effect.
import java.time.OffsetDateTime;
import static io.qala.datagen.RandomDate.beforeNow;
import static io.qala.datagen.RandomShortApi.*;
public class Dog {
private String name;
private OffsetDateTime timeOfBirth;
private double weight;
private double height;
public static Dog random() {
Dog dog = new Dog();
dog.name = alphanumeric(1, 100);
dog.timeOfBirth = nullOr(beforeNow().offsetDateTime());
dog.weight = positiveDouble();
dog.height = positiveInteger();
return dog;
}
}
@Alphanumeric(min = 2, max = 29, name = "middle value")
@Alphanumeric(length = 30, name = "max boundary")
@English(max=30)
void eachAnnotationInvokesTheTestOnceAndPassesParameters(String value, String name) {
assertTrue(value.length() >= 1 && value.length() <= 31, "Failed case: " + name);
}
@RandomInt(min = 1, name = "greater than zero")
@RandomInt(max = -1, name = "less than zero")
void zeroInt_isNotPassed(int param, String name) {
assertNotEquals(0, param, "Failed case: " + name);
}
import static io.qala.datagen.RandomValue.*;
import static io.qala.datagen.StringModifier.Impls.*;
import static io.qala.datagen.RandomShortApi.*;
Flexible API | Short API | Result |
---|---|---|
length(10).english() |
english(10) |
"DcRZUNPrED" |
between(1, 10).alphanumeric() |
alphanumeric(0, 10) |
"zG9G" |
between(1, 10).numeric() |
numeric(1, 10) |
"7167162" |
length(5).unicode() |
unicode(5) |
"䂞ꂣ뢧䯺婜" |
length(5).string("A_ B") |
" _B B" |
|
length(10).with(specialSymbol()).english() |
"hOzKEV#iWv" |
|
length(10).with(oneOf("_,")).english() |
"dwei,cNTfW" |
|
length(5).with(spaces()).numeric() |
"874 9 " |
|
length(3).with(spaceLeft()).english() |
" mT" |
|
length(4).with(spacesRight(2)).english() |
"hF " |
|
length(10).with(prefix("BLAH")).numeric() |
"BLAH453677" |
|
between(1, 10).alphanumerics(4) |
["cvA", "mTMDj0", "N", ""] |
|
mixedCase("blah") |
"bLaH" |
API | Result |
---|---|
nullOrEmpty() |
"" , null |
nullOrBlank() |
"" , " " , null |
nullOr(10L) |
null , 10L |
nullOr("string") |
null , "string" |
blankOr("string") |
"" , " " , null , "string" |
import static io.qala.datagen.RandomString.Type.*;
import static io.qala.datagen.RandomValue.*;
import static io.qala.datagen.Repeater.*;
repeat(length(4), NUMERIC).string("-").times(4)`
Result: "9338-8349-6940-7714"
import static io.qala.datagen.RandomValue.*;
import static io.qala.datagen.RandomShortApi.*;
Flexible API | Short API | Result |
---|---|---|
between(0, 100).integer() |
integer(100) |
89 |
between(-100, 100).integer() |
integer(-100, 100) |
-19 |
positiveInteger() |
3432145 |
|
Long() |
7635811362052252913 |
|
negativeDouble() |
-8.9946257128846746E18 |
import static io.qala.datagen.RandomElements.*;
import static io.qala.datagen.RandomShortApi.*;
Flexible API | Short API | Result |
---|---|---|
from("A", "B", "C", "D").sample() |
sample("A", "B", "C") |
"C" |
from("A", "B", "C", "D").sample(2) |
sampleMultiple(2, "A", "B", "C") |
["B", "A"] |
from("A", "B").sampleWithReplacement(3) |
["A", "A", "B"] |
|
from("A", "B", "C").shuffled() |
shuffled("A", "B", "C") |
["C", "A", "B"] |
import static io.qala.datagen.RandomValue.*;
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
between(f.parse("2015-01-01"), f.parse("2016-01-01")).date();
Result: 2015-11-30T08:33:20.349
// Requires Java8 and qala-datagen-java8types dependency
import static io.qala.datagen.RandomDate.*;
API | Result |
---|---|
plusMinus100Years().zonedDateTime() |
1937-09-27T01:16:15.925440485+01:00[Europe/Belgrade] |
since(yearAgo()).instant() |
2015-11-30T08:39:28.397051483Z |
before(now()).instant() |
-241279778-02-14T16:07:18.061693370Z |
between(yearsAgo(2), startOfMonth()).localDate() |
2014-09-30 |
import static io.qala.datagen.RandomShortApi.*;
API | Result |
---|---|
bool() or weighedTrue(0.5) |
false |
bools(4) |
[false, true, true, false] |
nullableBool() |
Boolean.TRUE |
import static io.qala.datagen.RandomShortApi.*;
Person person = new Person();
callOneOf(() -> person.firstName = english(5),
() -> person.lastName = english(5));
Result: Person[null, "PDGRq"]
callNoneOrMore(() -> person.firstName = english(5),
() -> person.lastName = english(5));
Result: Person[null, null]
callOneOrMore(() -> person.firstName = english(5),
() -> person.lastName = english(5));
Result: Person["LjxYh", "UXoBt"]
- Maven Central coordinates
- Occasional updates are posted in Twitter
- Our blog
To keep the lib tiny and get rid of extra dependencies (there are no transitive dependencies) some of the code was borrowed from these libs: Commons Lang, Commons Math. Hail to open source!