Generating Test data
You have seen that over and over: Test1, qwertyyui, asdfgh as data entered in development to test an application. Short of borrowing a copy of production data, having useful test data is a pain in the neck. For my currently limited exposure to development (after all I work as pre Sales engineer) I use a Java class that helps me to generate random result from a set of selection values. To make this work I used the following libraries:
- JodaTime: takes the headache out of date calculation
- gson: save and load JSON, in this case the random data
- Lorem Ipsum: generate blocks of text that look good Here you go:
package com.notessensei.randomdata ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.io.PrintWriter ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.Random ;
import org.joda.time.DateTime ;
import com.google.gson.Gson ;
import de.svenjacobs.loremipsum.LoremIpsum ;
/**
* Source of random data to generate test data for anything before use you need
* either load lists of your data using addRandomStringSource or load a JSON
* file from a previous run using loadDataFromJson
*
* @author NotesSensei
*
*/
public class RandomLoader {
/*
* How often should the random generator try for getRandomString with
* exclusion before it gives up
*/
public static final int MAX_RANDOM_TRIES = 100 ;
private Map < String, List < String >> randomStrings ;
private Random randomGenerator ;
/**
* Initialize all things random
*/
public RandomLoader ( ) {
this. randomStrings = new HashMap < String, List < String >> ( ) ;
this. randomGenerator = new Random ( new Date ( ). getTime ( ) ) ;
}
/**
* Adds or ammends a collection of values to draw from
*/
public void addRandomStringSource ( String sourceName, List < String > sourceMembers ) {
if ( ! this. randomStrings. containsKey (sourceName ) ) {
this. randomStrings. put (sourceName, sourceMembers ) ;
} else {
// We have a list of this name, so we add the values
List < String > existingList = this. randomStrings. get (sourceName ) ;
for ( String newMember : sourceMembers ) {
existingList. add (newMember ) ;
}
}
}
/**
* Get rid of a list we don't need anymore
*
* @param sourceName
*/
public void dropRandomStringSource ( String sourceName ) {
if ( this. randomStrings. containsKey (sourceName ) ) {
this. randomStrings. remove (sourceName ) ;
}
}
/**
* Gets a random value from a predefined list
*/
public String getRandomString ( String sourceName ) {
if ( this. randomStrings. containsValue (sourceName ) ) {
List < String > sourceCollection = this. randomStrings. get (sourceName ) ;
int whichValue = this. randomGenerator. nextInt (sourceCollection. size ( ) ) ;
return sourceCollection. get (whichValue ) ;
}
// If we don't have that list we return the requested list name
return sourceName ;
}
/**
* Get a random String, but not the value specified Good for populating
*travel to (exclude the from) or from/to message pairs etc
*
*@param sourceName
* from which list
*@param excludedResult
* what not to return
*@return
*/
public String getRandomStringButNot ( String sourceName, String excludedResult ) {
String result = null ;
for ( int i = 0 ; i < MAX_RANDOM_TRIES ; i++ ) {
result = this. getRandomString (sourceName ) ;
if ( !result. equals (excludedResult ) ) {
break ;
}
}
return result ;
}
/**
* For populating whole paragraphs of random text LoremIpsum Style
*/
public String getRandomParagraph ( int numberOfWords ) {
LoremIpsum li = new LoremIpsum ( ) ;
return li. getWords (numberOfWords ) ;
}
/**
*Get a date in the future
*/
public Date getFutureDate ( Date startDate, int maxDaysDistance ) {
int actualDayDistance = this. randomGenerator. nextInt (maxDaysDistance + 1 ) ;
DateTime jdt = new org. joda. time. DateTime (startDate ) ;
DateTime jodaResult = jdt. plusDays (actualDayDistance ) ;
return jodaResult. toDate ( ) ;
}
/**
* Get a date in the past, good for approval simulation
*/
public Date getPastDate ( Date startDate, int maxDaysDistance ) {
int actualDayDistance = this. randomGenerator. nextInt (maxDaysDistance + 1 ) ;
DateTime jdt = new org. joda. time. DateTime (startDate ) ;
DateTime jodaResult = jdt. minusDays (actualDayDistance ) ;
return jodaResult. toDate ( ) ;
}
/**
*Lots of applications are about $$ approvals, so we need a generator
*/
public float getRandomAmount ( float minimum, float maximum ) {
// between 0.0 and 1.0F
float seedValue = this. randomGenerator. nextFloat ( ) ;
return (minimum + ( (maximum - minimum ) * seedValue ) ) ;
}
/**
* Save the random strings to a JSON file for reuse
*/
public void saveDatatoJson ( OutputStream out ) {
Gson gson = new Gson ( ) ;
PrintWriter writer = new PrintWriter (out ) ;
gson. toJson ( this, writer ) ;
}
/**
* Load a saved JSON file to populate the random strings
*/
public static RandomLoader loadDataFromJson ( InputStream in ) {
InputStreamReader reader = new InputStreamReader (in ) ;
Gson gson = new Gson ( ) ;
RandomLoader result = gson. fromJson (reader, RandomLoader. class ) ;
return result ;
}
}
As usual YMMV
import java.io.InputStream ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.io.PrintWriter ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.Random ;
import org.joda.time.DateTime ;
import com.google.gson.Gson ;
import de.svenjacobs.loremipsum.LoremIpsum ;
/**
* Source of random data to generate test data for anything before use you need
* either load lists of your data using addRandomStringSource or load a JSON
* file from a previous run using loadDataFromJson
*
* @author NotesSensei
*
*/
public class RandomLoader {
/*
* How often should the random generator try for getRandomString with
* exclusion before it gives up
*/
public static final int MAX_RANDOM_TRIES = 100 ;
private Map < String, List < String >> randomStrings ;
private Random randomGenerator ;
/**
* Initialize all things random
*/
public RandomLoader ( ) {
this. randomStrings = new HashMap < String, List < String >> ( ) ;
this. randomGenerator = new Random ( new Date ( ). getTime ( ) ) ;
}
/**
* Adds or ammends a collection of values to draw from
*/
public void addRandomStringSource ( String sourceName, List < String > sourceMembers ) {
if ( ! this. randomStrings. containsKey (sourceName ) ) {
this. randomStrings. put (sourceName, sourceMembers ) ;
} else {
// We have a list of this name, so we add the values
List < String > existingList = this. randomStrings. get (sourceName ) ;
for ( String newMember : sourceMembers ) {
existingList. add (newMember ) ;
}
}
}
/**
* Get rid of a list we don't need anymore
*
* @param sourceName
*/
public void dropRandomStringSource ( String sourceName ) {
if ( this. randomStrings. containsKey (sourceName ) ) {
this. randomStrings. remove (sourceName ) ;
}
}
/**
* Gets a random value from a predefined list
*/
public String getRandomString ( String sourceName ) {
if ( this. randomStrings. containsValue (sourceName ) ) {
List < String > sourceCollection = this. randomStrings. get (sourceName ) ;
int whichValue = this. randomGenerator. nextInt (sourceCollection. size ( ) ) ;
return sourceCollection. get (whichValue ) ;
}
// If we don't have that list we return the requested list name
return sourceName ;
}
/**
* Get a random String, but not the value specified Good for populating
*travel to (exclude the from) or from/to message pairs etc
*
*@param sourceName
* from which list
*@param excludedResult
* what not to return
*@return
*/
public String getRandomStringButNot ( String sourceName, String excludedResult ) {
String result = null ;
for ( int i = 0 ; i < MAX_RANDOM_TRIES ; i++ ) {
result = this. getRandomString (sourceName ) ;
if ( !result. equals (excludedResult ) ) {
break ;
}
}
return result ;
}
/**
* For populating whole paragraphs of random text LoremIpsum Style
*/
public String getRandomParagraph ( int numberOfWords ) {
LoremIpsum li = new LoremIpsum ( ) ;
return li. getWords (numberOfWords ) ;
}
/**
*Get a date in the future
*/
public Date getFutureDate ( Date startDate, int maxDaysDistance ) {
int actualDayDistance = this. randomGenerator. nextInt (maxDaysDistance + 1 ) ;
DateTime jdt = new org. joda. time. DateTime (startDate ) ;
DateTime jodaResult = jdt. plusDays (actualDayDistance ) ;
return jodaResult. toDate ( ) ;
}
/**
* Get a date in the past, good for approval simulation
*/
public Date getPastDate ( Date startDate, int maxDaysDistance ) {
int actualDayDistance = this. randomGenerator. nextInt (maxDaysDistance + 1 ) ;
DateTime jdt = new org. joda. time. DateTime (startDate ) ;
DateTime jodaResult = jdt. minusDays (actualDayDistance ) ;
return jodaResult. toDate ( ) ;
}
/**
*Lots of applications are about $$ approvals, so we need a generator
*/
public float getRandomAmount ( float minimum, float maximum ) {
// between 0.0 and 1.0F
float seedValue = this. randomGenerator. nextFloat ( ) ;
return (minimum + ( (maximum - minimum ) * seedValue ) ) ;
}
/**
* Save the random strings to a JSON file for reuse
*/
public void saveDatatoJson ( OutputStream out ) {
Gson gson = new Gson ( ) ;
PrintWriter writer = new PrintWriter (out ) ;
gson. toJson ( this, writer ) ;
}
/**
* Load a saved JSON file to populate the random strings
*/
public static RandomLoader loadDataFromJson ( InputStream in ) {
InputStreamReader reader = new InputStreamReader (in ) ;
Gson gson = new Gson ( ) ;
RandomLoader result = gson. fromJson (reader, RandomLoader. class ) ;
return result ;
}
}
Posted by Stephan H Wissel on 18 January 2013 | Comments (0) | categories: Software