While learning TestNG, many people get confused when they read about the @DataProvider and @Factory annotations – when to use which annotation? and which is better? Let’s take a look at the differences between both annotations.
1. Difference between @Factory and @DataProvider
Below are the main differences between @Factory
and @DataProvider
annotations in TestNG.
- @DataProvider – A test method that uses
@DataProvider
will be executed multiple number of times based on the configuration provided in it. The test method will be executed using the same instance of the test class to which the test method belongs. - @Factory – A factory will execute all the test methods present inside a test class using separate instances of the class.
TestNG @Factory
is used to create instances of test classes dynamically. This is useful if you want to run the test class any number of times.
For example, if you have a test to login to a site and you want to run this test multiple times, then it is easy to use the TestNG factory where you create multiple instances of the test class and run the tests (maybe to test any memory leak issues).
Whereas, @DataProvider
is used to provide parameters to a test. If you provide the data provider to a test, the test will be run taking a different set of values each time. This is useful for a scenario like where you want to login to a site with a different set of username and password each time.
Let’s create an example that shows the clear difference between these two.
2. Using @DataProvider
The DataProviderClass
class contains the testMethod
and beforeClass
methods. testMethod
takes a String
argument and the value of the argument is provided by the DataProvider method, dataMethod()
.
The beforeClass()
method prints a message onto the console when executed, and the same is the case with testMethod()
. testMethod()
prints the argument passed onto it to the console when executed.
public class DataProviderClass
{
@BeforeClass
public void beforeClass() {
System.out.println("Before class executed");
}
@Test(dataProvider = "dataMethod")
public void testMethod(String param) {
System.out.println("The parameter value is: " + param);
}
@DataProvider
public Object[][] dataMethod() {
return new Object[][] { { "one" }, { "two" } };
}
}
Let’s run the above test.
Before class executed
The parameter value is: one
The parameter value is: two
PASSED: testMethod("one")
PASSED: testMethod("two")
As you can see from the preceding test results the class beforeClass()
is executed only one time irrespective of how many times the test method is executed.
3. Using @Factory
The SimpleTest
class contains the testMethod()
and beforeClass()
methods.
The constructor of the test class takes a String
argument value. Both beforeClass()
and testMethod()
print a message onto the console.
public class SimpleTest
{
private String param = "";
public SimpleTest(String param) {
this.param = param;
}
@BeforeClass
public void beforeClass() {
System.out.println("Before SimpleTest class executed.");
}
@Test
public void testMethod() {
System.out.println("testMethod parameter value is: " + param);
}
}
public class SimpleTestFactory
{
@Factory
public Object[] factoryMethod() {
return new Object[] {
new SimpleTest("one"),
new SimpleTest("two")
};
}
}
Let’s run the above test.
Before SimpleTest class executed.
testMethod parameter value is: two
Before SimpleTest class executed.
testMethod parameter value is: one
PASSED: testMethod
PASSED: testMethod
As you can see from the previous test results, the beforeClass()
method is executed before each execution of testMethod()
. This shows that factory implementation executes the test method for each individual instance of the test class.
As we saw earlier @DataProvider
executes the test method (testMethod()
) for a single instance of the test class.
Happy Learning !!
Leave a Reply