testng如何从工厂动态设置组?

testng how to dynamically set groups from Factory?

在我设置测试之前 class 如下代码: 1. Factory和test Dataprovider都使用excel作为dataprovider。 2. 在 Factory dataprovider table 中,它有一个列表 url 3. 每次都会在factory dataprovider table中找到url之一,在每个测试方法中运行测试..

public class Test {
    WebDriver driver;
    private String hostName;
    private String url;


    @Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
    public GetVariables(String hostName, String url) {
        this.hostName = hostName;
        this.url = url;

    }

    @BeforeMethod
    @Parameters("browser")
    public void start(String browser) throws Exception {

        driver = new FirefoxDriver();
        driver.get(url);
        Thread.sleep(1000);

    }

    @Test(priority = 10, dataProvider = "dataprovider Test A", dataProviderClass = xxx.class)
    public void TestA(Variable1,
            Variable2,Variable3) throws Exception {
        some test here...

    }

    @Test(priority = 20, dataProvider = "dataprovider Test B", dataProviderClass = xxx.class)
    public void TestB(Variable1,
            Variable2,Variable3)
            throws Exception {
        some test here...
    }

    @AfterMethod
    public void tearDown() {
        driver.quit();
    }

现在我想为不同 url 的每个测试动态分配不同的组。我正在考虑在@Factory 数据提供者中添加一个变量 'flag':

@Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url, String flag) {
    this.hostName = hostName;
    this.url = url;
    this.flag = flag;
}

That when flag.equals("A"), it will only run test cases in test groups={"A"}.
When flag.equals("B"), it will only run test cases in test groups ={"B"},
When flag.equals("A,B"), it will only run test cases in test groups ={"A","B"}

有什么办法可以做到吗?

谢谢!

TestNG 组提供 "flexibility in how you partition your tests" 但它不适用于条件测试集。为此,您只需使用普通的旧 Java.

您可以使用继承或组合(我推荐后者,请参阅第 16 条:优先使用组合而不是继承 来自 Effective Java)。

无论哪种方式,总体思路都是相同的:使用 Factory 创建测试 class 实例,动态创建具有适当测试注释的适当 class 类型 and/or 方法 运行.

示例:

  1. 继承

    import org.testng.annotations.Factory;
    import org.testng.annotations.Test;
    
    public class DemoTest {
        @Factory
        public static Object[] createTests() {
            return new Object[]{
                    new FlavorATest(),
                    new FlavorBTest(),
                    new FlavorABTest()
            };
        }
    
        /**
         * Base test class with code for both A-tests and B-tests.
         *
         * Note that none of these test methods are annotated as tests so that
         * subclasses may pick which ones to annotate.
         */
        public static abstract class BaseTest {
            protected void testA() {
                // test something specific to flavor A
            }
    
            protected void testB() {
                // test something specific to flavor B
            }
        }
    
        // extend base but only annotate A-tests
        public static class FlavorATest extends BaseTest {
            @Test
            @Override
            public void testA() {
                super.testA();
            }
        }
    
        // extend base but only annotate B-tests
        public static class FlavorBTest extends BaseTest {
            @Test
            @Override
            public void testB() {
                super.testB();
            }
        }
    
        // extend base and annotate both A-tests and B-tests
        public static class FlavorABTest extends BaseTest {
            @Test
            @Override
            public void testA() {
                super.testA();
            }
    
            @Test
            @Override
            public void testB() {
                super.testB();
            }
        }
    }
    
  2. 作文

    import org.testng.annotations.Factory;
    import org.testng.annotations.Test;
    
    public class DemoTest {
        @Factory
        public static Object[] createTests() {
            return new Object[]{
                    new FlavorATest(),
                    new FlavorBTest(),
                    new FlavorABTest()
            };
        }
    
        private static void testA() {
            // test something specific to flavor A
        }
    
        private static void testB() {
            // test something specific to flavor B
        }
    
        // only create A-test methods and delegate to shared code above
        public static class FlavorATest {
            @Test
            public void testA() {
                DemoTest.testA();
            }
        }
    
        // only create B-test methods and delegate to shared code above
        public static class FlavorBTest {
            @Test
            public void testB() {
                DemoTest.testB();
            }
        }
    
        // create A-test and B-test methods and delegate to shared code above
        public static class FlavorABTest {
            @Test
            public void testA() {
                DemoTest.testA();
            }
    
            @Test
            public void testB() {
                DemoTest.testB();
            }
        }
    }
    

您的工厂方法不会像您需要使用测试数据中的 "flag" 关闭和创建适当测试 classes 的实例那样简单。