Here's how you do this:
- Within your
.xls
file, create a sheet which represents a particular functionality. (For e.g, login
, compose
, address-book
etc., if I were to be taking the example of an emailing application)
- Now each sheet would have test data for various test cases, that test out that particular functionality.
- In your
@Test
method, you can create a new custom annotation (this would be a marker annotation), which would indicate the "sheet" name from which the data provider should be retrieving data from. If you are not keen on creating a new custom annotation, then you can make use of the "description" attribute of the @Test
annotation to capture this information.
- TestNG can natively inject a
Method
object to your @DataProvider
annotated method. Here the Method
object that was injected would represent the @Test
method for which the data provider is about to be invoked. So now you can retrieve the sheet name, either from the new custom annotation (or) from the description
attribute of the @Test
annotation to figure out which sheet name to query for data.
That should solve your issue.
Here's a sample that demonstrates the overall idea. You would need to enrich the data provider, such that it uses the sheet name to query data from the excel spreadsheet. My sample just excludes all of that, for the sake of demonstration.
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD})
public @interface SheetName {
String value() default "";
}
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
public class TestClass {
@Test(dataProvider = "dp")
@SheetName("one")
public void test1(String name) {
System.err.println("Name is " + name);
}
@Test(dataProvider = "dp")
@SheetName("two")
public void test2(int age) {
System.err.println("Age is " + age);
}
@DataProvider(name = "dp")
public Object[][] getData(Method method) {
String sheetName = getSheetName(method);
if (sheetName == null) {
// Handle the case, wherein our custom annotation is missing. That means the test perhaps
// expects
// either all of the data, or it could be a error case.
return new Object[][] {{}};
}
if ("one".equalsIgnoreCase(sheetName)) {
return new Object[][] {{"Cedric"}, {"Beust"}};
}
if ("two".equalsIgnoreCase(sheetName)) {
return new Object[][] {{1}, {2}};
}
// Handle the case, wherein we had a valid sheet name, but it represents a sheet that cant be
// found in our
// excel spreadsheet.
return new Object[][] {{}};
}
private String getSheetName(Method method) {
SheetName sheetName = method.getAnnotation(SheetName.class);
if (sheetName == null || sheetName.value().trim().isEmpty()) {
return null;
}
return sheetName.value();
}
}