Reputation: 4487
Setup:
@Test(dataProvider = "getData")
annotation.Problem:
I need to run all methods (tests) with one row of data, but as of now it keeps on repeating same tests on all rows i.e. if there is 7 rows of data then test 1 will run 7 times and then second test will start and same happen for second test and so on.
I want all tests to run for row 1 and then all tests run again for row2.
I am using Apache poi APIs to read data from ms-excel sheet. Java, testng and Selenium to automate the browser on Windows.
I have visited following link but didn't get the implementation:
https://dzone.com/articles/testng-run-tests-sequentially
Upvotes: 1
Views: 2899
Reputation: 9058
Factory allows one to create tests dynamically.
Assume this is the current setup...
SequentialTest.java - Sample portion
@Test(dataProvider="dp")
public void firstTest(int id, String account) {
System.out.println("Test #1 with data: "+id+". "+account);
}
Data.java - Sample portion
@DataProvider(name="dp")
public static Object[][] dataProvider() {
Object[][] dataArray = { {1, "user1"}, {2, "user2"} };
return dataArray;
}
Maybe you have the dataprovider in same class.
testng.xml - Relevant portion
< test name = "checks">
< classes >
< class name="....Sequential" />
< /classes >
< /test>
As per the article the changes that are required in the classes and xml.
SequentialTest.java - Create instance variables for each parameter that were earlier passed to the test method. Create a constructor with the instance variables. Remove the dataprovider part from Test annotation. Remove the parameters from the test methods.
private int id;
private String account;
public SequentialTest(int id, String account) {
this.id = id;
this.account = account;
}
@Test
public void firstTest() {
System.out.println("Test #1 with data: "+id+". "+account);
assertTrue(true);
}
Data.java - Need to separate the dataprovider method into a separate class (if not already) and add the factory method to it. Dataprovider remains the same.
@Factory(dataProvider="dp")
public Object[] createInstances(int id, String account) {
return new Object[] {new SequentialTest(id, account)};
}
testng.xml - Remove the existing portion. Need to mention only the name of the class containing the Factory method. Most important add the group-by-instances="true"
parameter which will get you the desired behaviour.
< test name="fact" group-by-instances="true">
< classes>
< class name="....Data"/>
< classes/>
< /test>
Upvotes: 2
Reputation: 78
While writing your dataprovider, you can add an attribute 'indices' to the dataprovider. For ex
//Define the index you want to return it to. Here it will return first row
@DataProvider(name = "dataProviderSample", indices = {0})
public Object[][] getSelectedData() {
return getInputData();
}
// Write your logic to generate data form excel/csv/json/xml inside the below method
private static Object[][] getInputData() {
return new Object[][]{{"Sample1", "Sample1", "Sample1"},
{"Sample2", "Sample2", "Sample2"},
{"Sample3", "Sample3", "Sample3"},
{"Sample4", "Sample5", "Sample5"}
};
}
Through the above approach, you can pass the expected index in your test method.
@Test(dataProvider = "dataProviderSample")
void testDataProvider(String fname, String lName, String num) {
System.out.println(fname);
System.out.println(lName);
System.out.println(num);
}
So by using this approach, you can pass one row at a time in your all test methods. But If you want to pass all rows of dataprovider in your test methods.
Upvotes: 1