TestNG – Difference Between @Factory and @DataProvider Annotation

Difference between @Factory and @DataProvider Annotation: We have discussed different topics Of TestNG, But most people are confused when it comes to finding out what the difference is between @Factory and @DataProvider, When to use DataProvider, and When to Use @Factory Annotation. So, in this post, we will discuss these two functionalities.

Difference Between @Factory & @DataProvider Annotation

Annotations like @Factory and @DataProvider are mainly used to reiterate the same test class with different data. These annotations will help the user to use the same class seamlessly without duplicating the test class code.

Here is the main difference between @Factory and @DataProvider annotation of TestNG:

@DataProvider Annotation

  • A test method that uses DataProvider will be executed multiple times based on the data provided by the DataProvider. That means this annotation parametrizes the particular test method and executes the test number of times based on the data provided by the DataProvider method.
  • The condition that needs to be met here is that the method marked as @DataProvider must return a 2D Object array (Object[][]) where each Object[] will be used as the input parameter to an iteration of the test method, which uses the data provider.
  • The Test method will be executed using the same instance of the test class to which the test method belongs.

@Factory Annotation

  • It can execute all the test methods inside a class with multiple data sets using a separate class instance.
  • We can instantiate a class multiple times rather than just a method.
  • The factory method should return an Object[]. This can be an array of Method calls or class objects.
  • The Test method will be executed using a separate instance of the respective class.

Difference between @Factory and @DataProvider Annotation In Tabular Format:

Feature@Factory@DataProvider
DefinitionUsed to create multiple instances of a test classUsed to mark a method that provides test data for one or more parameters of a test method
PurposeTo implement data-driven testingTo implement data-driven testing
Return TypeThe factory method must return an array of Object[] arrays.The @DataProvider must return a 2D Object[][] array.
Number of InstancesIt requires creating multiple instances of the same class.Internally, it creates only one instance of the class.
Object CreationDirectly involves creating objects in the Factory method.There is no need for explicit object creation, which is handled internally.
Implementation ApproachRequires manually creating and returning objects.Internally handles data supply without object creation.
Code ComplexityThis may lead to more code when creating multiple instances.Simpler code, as it internally handles data and instances.
Data-Driven TestingImplements data-driven testing by creating instances.Implements data-driven testing with a single instance.

Let us take the help of Example to understand these topics more clearly:

@DataProvider Annotation Example

package com.softwaretestingo.testng.factoryannotation;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderClass 
{
	@BeforeClass
	public void beforeClass() 
	{
		System.out.println("Before class executed");
	}

	@DataProvider
	public Object[][] message()
	{
		return new Object [][]{{"Manas", new Integer (123)}, {"Manoj", new Integer (456)}};
	}

	@Test (dataProvider="message")
	public void PrintMsg(String name, Integer id)
	{
		System.out.println("Names are: "+name+" " +id);
	}
}

Output:

Before class executed
Names are: Manas 123
Names are: Manoj 456
===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================

You can see there that the beforeclass is executed once, whereas the printing method is executed two times because the @DataProvider annotation passed two data sets.

@Factory Annotation Example

Simple Program:

package com.softwaretestingo.testng.factoryannotation;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
class SimpleTestClass
{
	private String param = " ";

	public SimpleTestClass(String param) 
	{
		this.param = param;
	}

	@BeforeClass
	public void beforeClass() 
	{
		System.out.println("Before SimpleTestClass class executed");
	}

	@Test
	public void testMethod()
	{
		System.out.println("testMethod parameter value is: " + param);
	}
}
public class SimpleFactoryAnnotation 
{
	@Factory
	public Object[] factoryMethod() 
	{
		return new Object[] 
				{
						new SimpleTestClass("one"),
						new SimpleTestClass("two")
				};
	}
}

If you see the output, we can find that the beforeClass method is executed before the test method, representing that factory implementation executes the test method for each instance of the test class.

Output:

Before SimpleTestClass class executed
testMethod parameter value is: two
Before SimpleTestClass class executed
testMethod parameter value is: one
PASSED: com.softwaretestingo.testng.factoryannotation.SimpleTestClass.testMethod
PASSED: com.softwaretestingo.testng.factoryannotation.SimpleTestClass.testMethod
===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================

Let’s go through with another example where we have implemented the @Factory and @DataProvider in a single program:

package com.softwaretestingo.testng.factoryannotation;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class FactoryDataProviderInSingleProgram 
{
	@DataProvider
	public Object[][] message()
	{
		return new Object [][]{	{"Manas" , new Integer (2023)},	{"Manoj", new Integer (2022)}};
	}
	@Test (dataProvider="message")
	public void PrintMsg(String name, Integer id)
	{
		System.out.println("Names are: "+name+" "+id);
	}

	@Test public void PrintSuccessfullMessage() 
	{
		System.out.println("Print the successful message"); 
	}
}

Runner Class:

package com.softwaretestingo.testng.factoryannotation;
import org.testng.annotations.Factory;
public class FactoryDataProviderInSingleProgramRunnerClass 
{
	@Factory 
	public Object[] factorymethod() 
	{ 
		return new Object[]{new FactoryDataProviderInSingleProgram(), new FactoryDataProviderInSingleProgram()}; 
	}
}

Output:

Names are: Manas 2023
Names are: Manoj 2022
Names are: Manas 2023
Names are: Manoj 2022
Print the successful message
Print the successful message
===============================================
    Default test
    Tests run: 4, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 6, Passes: 6, Failures: 0, Skips: 0
===============================================

If we run the above program, then you will find that the test method, which is associated with the @DataProvider, was executed four times, which means that it was executed two times for each instance, as we are passing two sets of data that’s why the count is 4.

The other @test method is executed two times for both instances. So, the total test case execution count is 6.

@DataProvider gives you the power to run a test method with different data sets, and @Factory gives you the power to run all methods inside a test class with different data sets. Though you can also test methods with @Factory, it depends on your use case and which approach fits it better.

I love open-source technologies and am very passionate about software development. I like to share my knowledge with others, especially on technology that's why I have given all the examples as simple as possible to understand for beginners. All the code posted on my blog is developed, compiled, and tested in my development environment. If you find any mistakes or bugs, Please drop an email to softwaretestingo.com@gmail.com, or You can join me on Linkedin.

Leave a Comment