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 |
---|---|---|
Definition | Used to create multiple instances of a test class | Used to mark a method that provides test data for one or more parameters of a test method |
Purpose | To implement data-driven testing | To implement data-driven testing |
Return Type | The factory method must return an array of Object[] arrays. | The @DataProvider must return a 2D Object[][] array. |
Number of Instances | It requires creating multiple instances of the same class. | Internally, it creates only one instance of the class. |
Object Creation | Directly involves creating objects in the Factory method. | There is no need for explicit object creation, which is handled internally. |
Implementation Approach | Requires manually creating and returning objects. | Internally handles data supply without object creation. |
Code Complexity | This may lead to more code when creating multiple instances. | Simpler code, as it internally handles data and instances. |
Data-Driven Testing | Implements 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.