TestNG @Factory annotation with @DataProvider in Selenium

This is one of the most important tutorials with respect to designing data-driven framework in the Selenium project. The combination of @Factory annotation and @DataProvider annotation helps in many ways to set the value of the instance variables. Thus, today’s agenda is about uses of @Factory in our Selenium project.

I have suggestions for some of the tutorials here which will help you in improving the strength of your knowledge bank:

These are some of the tutorials which will refresh your knowledge on parameterization through Excel sheet, JSON file, @DataProvider annotation, and @Parameters annotation.

@Factory annotation banner

What is the @Factory annotation in TestNG?

TestNG @Factory annotation is like any other annotation in TestNG. We need to import the following package and file before we implement this annotation in our project.

import org.testng.annotations.Factory;

@Factory basically runs multiple classes from a single class and return type of its method is 1D Object array.

Let’s look into the implementation of @Factory in Selenium project

How to run multiple classes from a single class using @Factory annotation?

If you want to handle multiple test cases (as the class definition in Java) from one class, then @Factory annotation helps you to do so. Let’s follow the steps below to run multiple classes from a single class.

Step# 1: Create multiple test classes

This is the first step where we have to create test classes to define the testable methods. So, at first, I created two test classes. Here are they:

TestCase1.java
package Test;

import org.testng.annotations.Test;

public class TestCase1 {
	
  @Test
  public void testMethod1() {
	  System.out.println("This is test method 1");
  }
}
TestCase2.java
package Test;

import org.testng.annotations.Test;

public class TestCase2 {
	
	 @Test
	  public void testMethod2() {
		  System.out.println("This is test method 2");
	  }
}

Step# 2: Create a single class with a @Factory annotation to trigger other classes

Now create a class which will control other test classes through @Factory annotation. The methods written inside @Factory has 1-D Object array as its return type. Here is the implementation.

TestNGFactoryClass.java
package Test;

import org.testng.annotations.Factory;

public class TestNGFactoryClass {
	
	
	@Factory()
	public Object[] getTestCaseClasses(){
		Object[] testObject = new Object[2];
		testObject[0] = new TestCase1();
		testObject[1] = new TestCase2();
		
		return testObject;
	}
	
 
}
testng.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="2" name="Test" >
    <classes>
      <class name="Test.TestNGFactoryClass"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
Console Output

@Factory annotation and multiple test classes

This was all about running multiple test classes from a single class using @Factory. Now coming to the implementation of @Factory and @DataProvider altogether.

How to use TestNG @Factory with @DataProvider annotation?

You can say that we can build multiple classes together, so what’s the benefit of using @Factory in our project. The real benefit of using @Factory annotation is visible with @DataProvider annotation when the constructor has some arguments and you need to set the value of those arguments.

Follow the steps below to pass the value to the test constructor using @Factory annotation and @DataProvider annotation.

Step# 1: Create a test class with a constructor having arguments

TestCaseWithConstructor.java
package Test;

import org.testng.annotations.Test;

public class TestCaseWithConstructor {
	
	private String str;
	
	public TestCaseWithConstructor(String st){
		this.str = st;
	}
  
	 @Test
	  public void testMethod() {
		  System.out.println("This is test method and value of str is- "+str);
	  }
}

Step# 2: Create a class which will send the value to the constructor using @Factory annotation and @DataProvider annotation

FactoryAndDataProvider.java
package Test;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;

public class FactoryAndDataProvider {
	
	
	@Factory(dataProvider="dataProvider")
	public Object[] setConstructorValue(String s){
		return new Object[]{new TestCaseWithConstructor(s)};
		
	}
 

  @DataProvider(name="dataProvider")
  public Object[][] dp() {
    return new Object[][] {
      new Object[] { "Test Data1"}
    };
  }
}
testng.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="2" name="Test" >
    <classes>
      <class name="Test.FactoryAndDataProvider"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
Console Output

@Factory annotation and @DataProvider

This is all about uses of TestNG @Factory annotation in Selenium project. Feel free to raise your questions and don’t miss to join our Facebook group.

Join Inviul fb group

Leave a Reply