In TestNG, DataProviders provide parameters for test methods, enabling them to run the same test with various data sets. But what if we need to pass parameters to a DataProvider from a test method? How can we achieve this?
There are several methods to achieve this goal, and one of them involves utilizing annotations.
So, what are annotations? Annotations serve as metadata to provide supplementary information about classes, interfaces, variables, methods, or fields. However, they do not directly impact the functioning of the code they are applied to.
Annotations start with “@”. There are many annotations in TestNG, like @Test, @BeforeMethod, @DataProvider etc.
So, how is an annotation an answer for passing data to a DataProvider from a test method?
It may not work independently, but when paired with java.lang.reflect.Method, it becomes quite effective. Therefore, let us delve into the concepts of java.lang.reflect.Method and annotations. Afterwards, we can utilize them in tandem to showcase how data can be passed from a method to a data provider.
Understanding of java.lang.reflect.Method
According to the documentation –
It provides information about, and access to, a single method on a class or interface.
Or in simpler words, it provides information about a method. Let’s see this with an example.
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class CodekruTest {
@DataProvider(name = "dataprovider_name")
public Object[][] dataProviderMethod(Method m) {
System.out.println("Method name: " + m.getName());
return new Object[][] {
{ "first", 2, 3 },
{ "second", 5, 6 },
{ "third", 8, 9 },
{ "fourth", 11, 12 }
};
}
@Test(dataProvider = "dataprovider_name")
public void test(String str, int a, int b) {
System.out.println("str = " + str + ", a = " + a + ", b = " + b);
}
}
On running the above test method, we will get the below output –
Method name: test
str = first, a = 2, b = 3
str = second, a = 5, b = 6
str = third, a = 8, b = 9
str = fourth, a = 11, b = 12
PASSED: test("third", 8, 9)
PASSED: test("first", 2, 3)
PASSED: test("fourth", 11, 12)
PASSED: test("second", 5, 6)
You may have observed that the test method’s name was displayed within the data provider. This allows you to access a method within a DataProvider.
We can use many other useful methods to access a method and its information inside a data provider.
Making custom annotation
Let’s make our own annotation named “CodekruTestAnnotation”
As demonstrated below, declare the annotation using the @interface keyword.
public @interface CodekruTestAnnotation {
}
Next step is to define the scope of the annotation.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CodekruTestAnnotation {
}
This gives our annotation runtime visibility.
Now, let’s add a field “website”.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CodekruTestAnnotation {
public String website() default "";
}
We declared one String parameter named “website” and an empty string as the default value.
Combining annotations with Method to send data to DataProvider
We will place the @CodekruTestAnnotation on our test method, as shown below.
@Test(dataProvider = "dataprovider_name")
@CodekruTestAnnotation(website = "Codekru")
public void test(String str, int a, int b) {
System.out.println("str = " + str + ", a = " + a + ", b = " + b);
}
We have set the attribute value for “website” as “Codekru” and will now attempt to retrieve this value in the data provider.
@DataProvider(name = "dataprovider_name")
public Object[][] dataProviderMethod(Method m) {
System.out.println("Method name: " + m.getName());
Annotation annotation = m.getAnnotation(CodekruTestAnnotation.class);
CodekruTestAnnotation annotationObj = (CodekruTestAnnotation) annotation;
System.out.println("Website name: " + annotationObj.website());
return new Object[][] { { "first", 2, 3 }, { "second", 5, 6 }, { "third", 8, 9 }, { "fourth", 11, 12 } };
}
Here is the whole code
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class CodekruTest {
@DataProvider(name = "dataprovider_name")
public Object[][] dataProviderMethod(Method m) {
System.out.println("Method name: " + m.getName());
Annotation annotation = m.getAnnotation(CodekruTestAnnotation.class);
CodekruTestAnnotation annotationObj = (CodekruTestAnnotation) annotation;
System.out.println("Website name: " + annotationObj.website());
return new Object[][] { { "first", 2, 3 }, { "second", 5, 6 }, { "third", 8, 9 }, { "fourth", 11, 12 } };
}
@Test(dataProvider = "dataprovider_name")
@CodekruTestAnnotation(website = "Codekru")
public void test(String str, int a, int b) {
System.out.println("str = " + str + ", a = " + a + ", b = " + b);
}
}
Output after the test method
Method name: test
Website name: Codekru
str = first, a = 2, b = 3
str = second, a = 5, b = 6
str = third, a = 8, b = 9
str = fourth, a = 11, b = 12
PASSED: test("fourth", 11, 12)
PASSED: test("third", 8, 9)
PASSED: test("first", 2, 3)
PASSED: test("second", 5, 6)
You can see that the website name is printed and this is how we can transfer the values from a test method to the data provider in TestNG.
We hope that you have liked the article. If you have any doubts or concerns, please write to us in the comments or mail us at admin@codekru.com.