【问题标题】:How to run conditional TestNG Tests with data from Excel如何使用 Excel 中的数据运行条件 TestNG 测试
【发布时间】:2017-11-23 19:44:03
【问题描述】:

我有一个包含多个 @Test 方法的类,每个方法都有不同的功能。

class myTests
{
@Test
test1()
{
...............
}

@Test
test2()
{
...............
}
}

我正在遵循数据驱动的方法,我在 Excel 中拥有数据。 excel表格中的每一行对应一个不同的测试用例,应该执行上述类中的测试方法。

以下是来自 excel 表的示例数据,其中包含方法名称作为参数之一(例如:test1、test2)以及一个标志,用于确定是否应在运行时选择执行案例(例如: y,n)

case1 data1 data2 data3........test1 y
case2 data4 data5 data6........test1 y
case3 data7 data8 data9........test2 y
case4 data10 data11 data12........test1 n  

以下是我的问题:

  1. 如何将案例映射到相应的测试方法
  2. 如何让具体案例根据flag跑起来

我的理解是,使用 DataProvider 注解,一个测试方法可以运行不同的输入数据。但是如果单个类中有多个测试方法,我不确定如何将测试方法与相应的测试数据映射。

我还尝试寻找可用于更改测试方法运行时行为的 IAnnotationTransformer,但找不到将标志数据从 excel 发送到转换器类的方法。

提前谢谢..

【问题讨论】:

    标签: java excel testng data-driven-tests testng-dataprovider


    【解决方案1】:

    如何做到这一点有很多细节,你可以做到,但这需要你进行大量的定制。 TestNG 中没有任何东西可以为您提供这种开箱即用的功能。

    IAnnotationTransformer 不会帮助你,因为这个监听器只考虑方法而不知道实例。它也在任何东西运行之前运行,并且没有办法让你进行这个迭代。这样就可以排除了。

    您最好的选择是使用@Factory@DataProvider,其中@Factory 将产生您的测试类的一个实例,并且您的所有测试方法都必须强制同一个测试类的一部分。

    这就是想法:

    • 在您的数据源中创建一个附加列,该列表示应该基本上使用数据源的类。
    • 构建一个数据提供者,使其读取上述数据源,过滤掉其完全限定类名与当前数据提供者的封闭类匹配的所有行。
    • 还应构建数据提供程序以创建映射(键是测试方法名称,值是要用于不同迭代的值列表)。
    • 一旦它拥有所有过滤的行,它就只创建一行测试数据,这样,TestNG 只创建一个测试类实例。
    • 让您的测试类也实现IHookable 接口,以便您决定运行哪个测试方法以及可以跳过哪些测试方法。
    • 现在,如果一个方法满足正在运行的检查,您将基本上让测试方法循环遍历它拥有的所有测试数据(因此,与数据提供程序设置不同,它始终有 1 个测试方法将在循环中针对所有数据运行其中 TestNG 会自动为您执行此操作),并且您使用软断言来断言所有验证。这样,您的测试将在所有迭代完成后通过/失败。

    这是一个示例,展示了其中的一些实际操作。

    import org.testng.IHookCallBack;
    import org.testng.IHookable;
    import org.testng.ITestResult;
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Factory;
    import org.testng.annotations.Test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class TestclassSample implements IHookable {
    
        private List<String> methodsToRun = new ArrayList<>();
    
        @Factory(dataProvider = "dp")
        public TestclassSample(List<String> methodsToRun) {
            this.methodsToRun = methodsToRun;
        }
    
        @Override
        public void run(IHookCallBack callBack, ITestResult testResult) {
            String testMethodName = testResult.getMethod().getMethodName();
            if (methodsToRun.contains(testMethodName)) {
                System.err.println("About to run " + testResult.getMethod().getMethodName());
                callBack.runTestMethod(testResult);
            } else {
                testResult.setStatus(ITestResult.SKIP);
            }
        }
    
        @Test
        public void testMethod() {
            System.err.println("testMethod()");
        }
    
        @Test
        public void anotherTestMethod() {
            System.err.println("anotherTestMethod()");
        }
    
        @Test
        public void thirdTestMethod() {
            System.err.println("thirdTestMethod()");
        }
    
        @DataProvider(name = "dp")
        public static Object[][] getData() {
            return new Object[][]{
                    {Arrays.asList("testMethod", "thirdTestMethod")}
            };
        }
    }
    

    这是输出:

    About to run testMethod
    testMethod()
    About to run thirdTestMethod
    thirdTestMethod()
    
    Test ignored.
    
    ===============================================
    Default Suite
    Total tests run: 3, Failures: 0, Skips: 1
    ===============================================
    

    【讨论】:

    • 非常感谢您抽出时间回复。 :) 我正在从事其他一些任务,这就是为什么我没有机会尝试这种方法的原因。但是,我最近针对示例场景对此进行了验证,并且正在执行测试。还有一件事我想澄清一下。当我用不同的数据集验证相同的测试方法时,该方法的报告仅针对 1 个实例生成。我想知道是否有办法让每次迭代的详细信息都反映在生成的默认报告中。如果没有,还有其他更好的方法吗?
    猜你喜欢
    • 2016-03-19
    • 2011-04-26
    • 1970-01-01
    • 2019-10-20
    • 2012-09-23
    • 2020-06-03
    • 2016-03-04
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多