工厂允许您动态创建测试。例如,假设您想创建一个测试方法,该方法将多次访问网站上的页面,并且您想用不同的值调用它:

    1. public class TestWebServer {
    2. @Test(parameters = { "number-of-times" })
    3. public void accessPage(int numberOfTimes) {
    4. while (numberOfTimes-- > 0) {
    5. // access the web page
    6. }
    7. }
    8. }
    1. <test name="T1">
    2. <parameter name="number-of-times" value="10"/>
    3. <classes>
    4. <class name= "TestWebServer" />
    5. </classes>
    6. </test>
    7. <test name="T2">
    8. <parameter name="number-of-times" value="20"/>
    9. <classes>
    10. <class name= "TestWebServer"/>
    11. </classes>
    12. </test>
    13. <test name="T3">
    14. <parameter name="number-of-times" value="30"/>
    15. <classes>
    16. <class name= "TestWebServer"/>
    17. </classes>
    18. </test>

    这很快就会变得无法管理,因此,您应该使用工厂:

    1. public class WebTestFactory {
    2. @Factory
    3. public Object[] createInstances() {
    4. Object[] result = new Object[10];
    5. for (int i = 0; i < 10; i++) {
    6. result[i] = new WebTest(i * 10);
    7. }
    8. return result;
    9. }
    10. }

    现在新的测试类是:

    1. public class WebTest {
    2. private int m_numberOfTimes;
    3. public WebTest(int numberOfTimes) {
    4. m_numberOfTimes = numberOfTimes;
    5. }
    6. @Test
    7. public void testServer() {
    8. for (int i = 0; i < m_numberOfTimes; i++) {
    9. // access the web page
    10. }
    11. }
    12. }

    您的testng.xml只需要引用包含工厂方法的类,因为测试实例本身将在运行时创建:

    1. <class name="WebTestFactory" />

    或者,如果以编程方式构建测试套件实例,您可以以与测试相同的方式添加工厂:

    1. TestNG testNG = new TestNG();
    2. testNG.setTestClasses(WebTestFactory.class);
    3. testNG.run();

    工厂方法可以像@Test和@Before/After一样接收参数,并且它必须返回Object[]。返回的对象可以是任何类(不一定与工厂类相同),它们甚至不需要包含 TestNG 注释(在这种情况下它们将被 TestNG 忽略)。
    工厂也可以与数据提供者一起使用,您可以通过将@Factory注释放在常规方法或构造函数上来利用此功能。这是构造函数工厂的示例:

    1. @Factory(dataProvider = "dp")
    2. public FactoryDataProviderSampleTest(int n) {
    3. super(n);
    4. }
    5. @DataProvider
    6. static public Object[][] dp() {
    7. return new Object[][] {
    8. new Object[] { 41 },
    9. new Object[] { 42 },
    10. };
    11. }

    该示例将使 TestNG 创建两个测试类,使用值 41 调用构造函数,使用值 42 调用另一个。