TestNG – @Factory vs @DataProvider

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.

  1. @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.
  2. @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 !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

0 thoughts on “TestNG – @Factory vs @DataProvider”

  1. 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.

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.