I have generated a list of Objects of type Household Object, that has a String name and a List colours, from a CSV file. I want to run the same tests on every element in my list of Household objects. So:
@Test(priority = 1)
test1(String name){
assert something
}
@Test(priority =2)
test2(String colour){
assert something
}
So if I have a Household object: Name = Chair, colours = [pink,yellow,blue] I want to run test 1 with Name 'chair' once, and then I want to run Test 2 for every colour in the list. I want to do this for every object in my list of elements.
I am trying to use data provider:
@DataProvider
public Object[][] data() throws CsvValidationException, IOException, URISyntaxExcepton {
CVS reader = new CVS();
houseHoldObjects = reader.getHouseHoldObjects();
return new Object[][] {
{
}
};
}
However I don't understand how I can do this for every object in the list, and for every colour in each object.
TestNg has features to implement such advanced configuration.
However you'll need to apply the different features combo with accuracy.
So let's define the request explicitly:
Solution:
1 To parametrize the whole class we'll use TestNg @Factory feature in combination with @DataProvider.
For that purpose we'll create static @DataProvider
which will return the data in the described manner: String name and List of colors - provideTestClassData
.
Note, I'll not solve CSV parsing/transform issue, I assume it'll be solved separately.
2 Also I'll create class constructor with the required properties initialisation.
3 For test2
I'll add @DataProvider
for colors - provideColours
.
package org.example;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class ColoredFurnitureTest {
final String name;
final List<String> colours;
@Factory(dataProvider = "provideTestClassData")
public ColoredFurnitureTest(String name, List<String> colours) {
this.name = name;
this.colours = colours;
}
@Test(priority = 1)
public void test1() {
System.out.println("Do test1 for " + name);
//assert something
}
@Test(priority = 2, dataProvider = "provideColours")
public void test2(String colour) {
System.out.println("Do test2 for " + name + "with color " + colour);
//assert something
}
@DataProvider
public Object[][] provideColours() {
List<Object[]> data = new ArrayList<>();
for (String c : colours) {
data.add(new Object[]{c})
}
data.toArray();
}
// assume CSV data will be parsed somehow to follow next structure
@DataProvider
public static Object[][] provideTestClassData() {
return new Object[]{
new Object[]{"Chair", Arrays.asList("pink", "yellow", "blue")},
new Object[]{"Table", Arrays.asList("black", "white", "green")},
new Object[]{"Closet", Arrays.asList("blue", "orange")},
};
}
Run the whole class tests one-by-one per dataset
If run the class without any additional configuration the run order will be next:
Do test1 for Chair
Do test1 for Table
Do test1 for Closet
Do test2 for Chair with color pink
Do test2 for Chair with color yellow
Do test2 for Chair with color blue
Do test2 for Table with color black
Do test2 for Table with color white
Do test2 for Table with color green
Do test2 for Closet with color blue
Do test2 for Closet with color orange
To run all class methods one-by one per dataset we need to enable group-by-instances="true"
testNg feature. This can be defined in TestNg suite xml.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="ColoredFurnitureTest Suite">
<test name="ColoredFurnitureTest" group-by-instances="true">
<classes>
<class name="org.example.ColoredFurnitureTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
if run with this option, the order will be next:
Do test1 for Chair
Do test2 for Chair with color pink
Do test2 for Chair with color yellow
Do test2 for Chair with color blue
Do test1 for Table
Do test2 for Table with color black
Do test2 for Table with color white
Do test2 for Table with color green
Do test1 for Closet
Do test2 for Closet with color blue
Do test2 for Closet with color orange