We would like to run some of our tests each against a set of data values, verifying that the same conditions hold true for each. The data is currently stored in either flat files or in simple Excel spreadsheets.
My first thought was to create a TestNG DataProvider that would load the data from the file and be used to call the test method once for each data value. My problem is that different tests need to load data from different files and there doesn't appear to be any way to send a parameter to the DataProvider. Does anyone know if this is possible?
Ideally, I would like my code to look like the following (simplified example):
public class OddTest {
@DataProvider(name = "excelLoader")
public Iterator<Object[]> loadExcelData(String fileName) {
...
}
@Test(dataProvider = "excelLoader" dataProviderParameters = { "data.xls" })
public void checkIsOddWorks(int num)
assertTrue(isOdd(num));
}
}
A more generic way of doing this would be to make use of the
groups
annotation to build a custom list of values:Alternatively you could also create your own annotation class that takes in custom elements so that you could do something more like:
You can access all defined parameters in your DataProvider using TestNG's dependency injection capabilies. This is some example DataProvider in need of the "test_param" parameter:
This requires "test_param" to be defined in you
suite.xml
:See the TestNG JavaDoc for details on the ITestContext class.
Taken from the TestNG docs:
If you declare your @DataProvider as taking a
java.lang.reflect.Method
as first parameter, TestNG will pass the current test method for this first parameter. This is particularly useful when several test methods use the same @DataProvider and you want it to return different values depending on which test method it is supplying data for.For example, the following code prints the name of the test method inside its @DataProvider:
and will therefore display:
This can also be combined with the solution provided by desolat to determine data from the context and the method accordingly:
The answer from yshua is a bit limiting because you still have to hardcode the filepaths inside your data provider. This means you'd have to change the source code and then recompile to just rerun the test. This defeats the purpose of using XML files to configure the test run.
A better, definitely more hacky, kludge of a solution would be to create a dummy @test method that runs before suite, takes your filepaths as parameters and saves this information within the Class housing these test methods.
This solution isn't perfect, but until TestNG permits better parameter passing (Maybe this has changed) this might be viable for your needs.
To add to my answer above, heres the complete code of how you can do it using EasyTest Framework:
And so on. If you want to know more about how the @DataLoader annotation works in EasyTest, look at the following: https://github.com/EaseTech/easytest/wiki/EasyTest-:-Loading-Data-using-Excel
Note that you can use XML, Excel, CSV or your own custom loader to load the data and all can be used in the same test class at once as shown in this example : https://github.com/EaseTech/easytest/blob/master/src/test/java/org/easetech/easytest/example/TestCombinedLoadingAndWriting.java
I hope it was useful.