'How can I structure multiple 2D arrays of test data into a properties file and read them for my tests?
I need to save all the test data into a properties
file or a JSON
file (since they're easier to read than an XML
). I'm thinking of using a single properties file for storing data for the entire project. Not sure whether that's doable or not.
I am using TestNG
test framework with it's @DataProvider
annotation to tag a function that will return a 2D array. Here's an example of what this can look like:
/*
* This returns 2 parameters for each test execution
*/
@DataProvider(name = "info on cars")
public Object[][] testDataOnCars(){
return new Object[][]{
{"Mercedes as key", "Value with any special char ~!@#$%^&*()_'\",./<>?+"}, {"Jaguar", "<>?,./;':\"[]\{}|~!@#$%^&*()_+`"}
}
}
The corresponding test for this could look like:
@Test(dataprovider = "info on cars")
public void testAllCars(String carName, String carDetails){
// Do something with carName and carDetails
}
Some test might require a different number of parameters for a different dataset. For example:
/*
* This returns 4 parameters for each test execution
*/
@DataProvider(name = "info on bank statements")
public Object[][] testDataOnBankStatements(){
return new Object[][]{
{"Credit card payment", "200", "debit", "5th May, 2022"},
{"Salary credit", "5200", "credit", "5th May, 2022"},
}
}
This might be consumed by test function with 4 params:
@Test(dataprovider = "info on bank statements")
public void testAllCars(String description, Integer amount, String debitOrCredit, String date){
// Do something with the 4 params
}
Does anyone know:
- How can I organize test data into a file? Is it better to have a properties file or a JSON file or some other kind of file? It is a 2D array with many parameters tied together.
- Is it advisable to store different test data into the same properties file? Or should I have a separate file for each kind of test data (like 1 file for bank stuff - 5 parameters, another file for travel stuff - 3 parameters etc).
- How do I read this kind of structured data from the file and pass them as a 2D array of
Object[][]
?
Solution 1:[1]
Say you have src/test/resources/test_data.json
file which looks like
{
"infoOnCars": [
["Mercedes as key", "Value with any special char ~!@#$%^&*()_'\\\",./<>?+"],
["Jaguar", "<>?,./;':\\\"[]\\{}|~!@#$%^&*()_+`"]
],
"infoOnBankStatements": [
["Credit card payment", "200", "debit", "5th May, 2022"],
["Salary credit", "5200", "credit", "5th May, 2022"]
]
}
Then you can add org.json
dependency to your project and implement the following:
public class DataProviderTest {
private JSONObject jsonObject;
private JSONObject getJsonObject() throws URISyntaxException, IOException {
if(jsonObject == null){
jsonObject = new JSONObject(
Files.readString(Paths.get(DataProviderTest.class.getClassLoader().getResource("test_data.json").toURI()))
);
}
return jsonObject;
}
@DataProvider(name = "cars")
Iterator<Object[]> getCars() throws URISyntaxException, IOException {
return getIterator(getJsonObject(), "infoOnCars");
}
@DataProvider(name = "banks")
Iterator<Object[]> getBanks() throws URISyntaxException, IOException {
return getIterator(getJsonObject(), "infoOnBankStatements");
}
Iterator<Object[]> getIterator(JSONObject jsonObject, String key){
Map<String, Object> map = jsonObject.toMap();
Object val = map.get(key);
if(val instanceof ArrayList){
Iterator<ArrayList> valArray = ((ArrayList) val).iterator();
return new Iterator<>() {
@Override
public boolean hasNext() {
return valArray.hasNext();
}
@Override
public Object[] next() {
return valArray.next().toArray();
}
};
}
return null;
}
@Test(dataProvider = "cars")
public void test1(String carName, String carDetails){
System.out.println(">>>> Cars test started");
System.out.println("Car name: " + carName);
System.out.println("Car details: " + carDetails);
}
@Test(dataProvider = "banks")
public void test2(String description, String amount, String debitOrCredit, String date){
System.out.println(">>>> Bank test started");
System.out.println("Description: " + description);
System.out.println("Amount: " + amount);
System.out.println("Debit / Credit: " + debitOrCredit);
System.out.println("Date: " + date);
}
}
It would parse all data as strings. So that you would need to do some conversion to use numbers as numbers.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Mugen |