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
annotaions 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 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.
2. 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 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 !!
Yeshwanth
Hi,
is it possible to collect the test data from testFactory and run a battery of test methods where each testMethod represent different scenarios.
For example :
I have a test data in JSON file
ex : Json data
{
testId1 : “abc”,
testId2:”def”
}
I need to use the above data and the testId1’s data should be used for testMethod1, testId2’s data should be used for testMethod2.
Kindly help me if you get any insights on this.