Search code examples
javaseleniumtestng-dataprovider

Test with DataProvider repeated some number of times with a different DP parameter for each time


I have 20 or more tables. Number of tables could be different. To determine number of tables I use driver.findElements(By.xpath(...)).size() functionality.

For one table I created DataProvider method, that returns an object:

@DataProvider
    public Object[][] tableValues() throws Exception {
    .........

    int c = 0; // here I use HashMap<String, String> object 
    //filled with entry.getValue = column label, entry.getKey() = cell value of column

    Object obj[][] = new Object[tableMap.size()][4];
    print("========== DataProvider object generating...");
    print("========== Size of tableMap: "+tableMap.size());
    for (Map.Entry entry: tableMap.entrySet()) {
        obj[c][0] = fileName;
        obj[c][1] = entry.getValue();
        obj[c][2] = entry.getKey();
        obj[c][3] = false;
        c++;
    }
    obj[tableMap.size()-1][3]=true;
    return obj;
}

In this case I have a fileName = "file name 1" for the first table.

I use this object to assert that every value of table could be found in database through web search functionality. For the search I use only entry.getKey value, but use fileName and entry.getValue in extent reports to show where the value is located.

I hardcoded fileName here, checking values only for table with this fileName.

I want to repeat both DataProvider and Test method "number of tables" times, using for each time the next table number starting from 01. I could say it in different way: For example, I've got 20 tables. I should use 20 DataProviders with 20 different fileNames and I should run @Test(dataProvider = "tableValues") 20 times also with different table names. I could not get 20 table sets in one big DataProvider. I could do it, but I should not do it, because of tables' values could change after 10-20 minutes and it could change test results. I get restricted number of rows and quickly check them. Then I go to another table fetching values, asserting values and so on.

@Test(dataProvider = "tableValues")
public void ValuesAsserting(String fileName, String columnName, String cellValue, boolean flag) throws Exception {
    if (cellValue != null) {                        //Steps:
        inputField(cellValue, "searchFieldXpath");  //1
        buttonClick("searchButtonXpath");           //2
        waitLoaderDisplayed();                      //3
        waitLoaderHidden();                         //4
        print("Verifying "+fileName+": "+columnName+": "+cellValue);
        logger = extent.createTest("Verifying of "+fileName+" value: "+"\n"+columnName+": "+cellValue);
        assertValueIsInResults(cellValue,"searchResultsXpath"); //5
        // asserts file's generation time before and after testing
        scanTimeAssert(flag);                       //After tests
    }
}

Solution

  • I've found a solution in TestNG documentation. @Factory annotation helps to resolve it.

    // It is my main class Factory provides with file's number required for xpath to open it and go further:
    public class AllTablesTest extends BaseTest {
        // It is the main thing I added to get it worked within factory:
        private int fNumber;
        public AllTablesTest(int fileNumber) {
            this.fNumber = fileNumber;
        }
        ........
    }
    
    // WebTestFactory class I get from TestNG documentation and changed it to get desirable number of files:
    public class WebTestFactory extends BaseTest{
        int numberOfFiles;
    
        @Factory
        public Object[] createInstances() throws Exception {
            getDriver("Chrome");
            getUrl("adminUrl");
            login(getValue("adminEmail"),getValue("adminPass"));
            numberOfFiles = getNumberOfFiles();
            Object[] result = new Object[numberOfFiles];
            for (int i=0; i<numberOfFiles; i++) {
                result[i]=new AllTablesTest(i+1);
            }
            return result;
        }