TestNG @Factory annotation is used to specify a method as a factory for providing objects to be used by TestNG for test classes. The method marked with @Factory
annotation should return Object array.
TestNG @Factory Annotation
TestNG Factory is useful when you want to run multiple test classes through a single test class. Let’s see a quick example of TestNG Factory annotation.
Let’s say we have two Test classes with few test methods defined.
1 2 3 4 5 6 7 8 9 10 |
package com.journaldev.utils; import org.testng.annotations.Test; public class Test1 { @Test public void test1() { System.out.println("Test1 test method"); } } |
1 2 3 4 5 6 7 8 9 10 |
package com.journaldev.utils; import org.testng.annotations.Test; public class Test2 { @Test public void test2() { System.out.println("Test2 test method"); } } |
Now we can define a Factory method that returns the Object array of above classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.journaldev.utils; import org.testng.annotations.Factory; public class TestNGFactory { @Factory() public Object[] getTestClasses() { Object[] tests = new Object[2]; tests[0] = new Test1(); tests[1] = new Test2(); return tests; } } |
Below image shows the output of running above class as TestNG test class.
Here is the output produced in the Eclipse Console.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[RemoteTestNG] detected TestNG version 6.14.3 Test1 test method Test2 test method PASSED: test1 PASSED: test2 =============================================== Default test Tests run: 2, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== |
Note that if we do the maven build and there are more TestNG test classes present, all of them will also get executed. I have another TestNG test class and below is the output from maven build.
1 2 3 4 5 6 7 8 9 10 |
Running TestSuite Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@3224f60b Test2 test method Test3 test method Test1 test method Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.342 sec Results : Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 |
So if the Test class is getting returned by any factory method, then it’s excluded from the default test suite.
We can also create multiple @Factory methods in the same test class or in different test classes.
TestNG Factory with DataProvider
When we do project build, all our test cases are being executed. So what’s the benefit of using Factory method?
Well, it’s beneficial when you use it with DataProvider and your test class constructor has arguments.
Let’s say our Test1
class is defined as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.journaldev.utils; import org.testng.annotations.Test; public class Test1 { private String str; public Test1(String s) { this.str = s; } @Test public void test1() { System.out.println("Test1 test method. str = "+str); } } |
If we simply run this class as TestNG test class, then it will assign the default value for the string argument of the constructor and produce following output.
1 2 3 4 |
Test1 test method. str = Default test PASSED: test1 |
In this case, we can use DataProvider along with Factory to provide inputs for the constructor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.journaldev.utils; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; public class TestNGFactory { @Factory(dataProvider = "dp") public Object[] getTestClasses(String s) { Object[] tests = new Object[2]; tests[0] = new Test1(s); tests[1] = new Test2(); return tests; } @DataProvider public Object[] dp() { return new Object[] {"A", "B"}; } } |
When we run above test class, it produces following output.
1 2 3 4 5 6 7 8 9 10 |
Test1 test method. str = A Test1 test method. str = B Test2 test method Test2 test method PASSED: test1 PASSED: test1 PASSED: test2 PASSED: test2 |
Summary
TestNG Factory methods are useful when your test classes have constructors with arguments or you want to create the different set of test classes and execute them at once.