当前位置: 首页 > 知识库问答 >
问题:

有没有办法使用TestNG数据提供程序为测试用例命名?

许明朗
2023-03-14

我正在使用@DataProvider使用TestNG 6.14.3Java编写单元测试

我想实现的目标:

  1. 我想为每个数据提供程序案例命名

我所尝试的:

>

  • 我添加了一个额外的参数并遵循了此指南,问题是现在我在每个我不想要的测试中都有一个未使用的参数。

    创建一个忽略第一个参数的自html" target="_blank">定义数据提供程序注释,这不起作用,因为我找不到将其与TestNG集成的方法。

    我的问题:

    1. 是否有一种内置的方式为测试用例提供特定的名称?
    2. 如果1的答案为“否”:是否有办法集成自定义DataProvider或在将数据提供给测试本身之前拦截数据?
    3. 即使在遵循本指南之后,我仍然将其他参数视为Intellij中的测试名称postfix,这正常吗?如果不是,我将发布我的示例代码。

    非常感谢。

  • 共有2个答案

    梅宏盛
    2023-03-14

    你可以这样做:

    public class TestName {
    
        @DataProvider(name = "nameAndOthers")
        Iterator<Object[]> provideData(ITestContext testContext){
            Object[][] data = new Object[][]{
                    {"name1", 1, 2},
                    {"name2", 3, 4},
                    {"name3", 5, 6},
            };
            Iterator<Object[]> originalDataIterator = Arrays.asList(data).iterator();
            return new Iterator<Object[]>() {
                @Override
                public boolean hasNext() {
                    return originalDataIterator.hasNext();
                }
    
                @Override
                public Object[] next() {
                    Object[] next = originalDataIterator.next();
                    testContext.getCurrentXmlTest().setName(next[0].toString());
                    return Arrays.copyOfRange(next, 1, next.length);
                }
            };
    
        }
    
        @Test(dataProvider = "nameAndOthers")
        void testName(Integer one, Integer two){
            System.out.println(one + ": " + two);
        }
    
    }
    

    输出为:

    1: 2
    3: 4
    5: 6
    

    测试将从您的数据中获取它们的名称:

    公西英叡
    2023-03-14

    一种解决方案可能是在测试类中声明一个String名称数组并按顺序排列。如果您没有并行运行测试,这将起作用。

    否则,您可以使用工厂注释,它可以从数据提供程序获取输入,然后创建测试对象。

    @Factory(dataProvider = "data")
    public Object[] createInstances(String val, String name) {
        return new Object[] { new MyTest(name) };
    }
    
    @DataProvider
    public Object[][] data() {
        return new Object[][] { { "a", "one" }, { "b", "two" } };
    }
    

    因此,您需要在测试类中设置一个name字段,该字段将使用构造函数设置。结合链接中建议的代码来设置测试名称,您可以这样做:

    public class MyTest implements ITest {
    
        private String name;
        private ThreadLocal<String> testName = new ThreadLocal<>();
    
        public MyTest() {
        }
    
        public MyTest(String name) {
            this.name = name;
        }
    
        @Factory(dataProvider = "data")
        public Object[] createInstances(String name) {
            return new Object[] { new MyTest(name) };
        }
        
        @DataProvider
        public Object[][] data() {
            return new Object[][] { { "one" }, { "two" } };
        }
    
        @BeforeMethod
        public void beforeMethod(Method method) {
            testName.set(method.getName() + "_" + name);
        }
    
        @Test
        public void test() {
            System.out.println(name);
        }
    
        @Override
        public String getTestName() {
            return testName.get();
        }
    }
    

    编辑:无需使用出厂代码,可通过以下方式实现。这需要在ITestContext中设置相关详细信息:

    @DataProvider
    public Object[][] data(ITestContext ctx) {
        ctx.setAttribute("names", new String[]{"one", "two"});
        ctx.setAttribute("index", 0);
        
        return new Object[][] { {"val1", "data1"}, {"val2", "data2"} };
    }
    

    现在,在beforeMethod(注入)中,还包括:

    @BeforeMethod
    public void beforeMethod(ITestContext ctx, Method method) {
        testName.set(method.getName() + "_" + getName(ctx));
    }
    
    // Create a helper method getName.
    private static String getName(ITestContext ctx) {
        int index = (int) ctx.getAttribute("index");
        // get the name based on the current index.
        String name = ((String[]) ctx.getAttribute("names"))[index++];
        
        // update the attribute with the incremented index.
        ctx.setAttribute("index", index);
        return name;
    }
    
    @Test(dataProvider = "data") 
    public void yourTest(String val, String data) {
        // .............
    }
    

    注意:当测试并行运行时,这将无法按预期工作。

     类似资料:
    • 我使用了test dat provider和factory来处理示例数据,更像是从具有多个值的excel行中读取数据。因此,每个映射表示每行的列名和值,并将其添加到列表中,以获得从excel读取的所有值。现在我返回

    • 问题内容: 我发现C#中的命名参数功能在某些情况下非常有用。 如果要在JavaScript中使用该怎么办? 我不想要的是: 我已经使用过这种方法。还有另一种方法吗? 我可以使用任何库来做到这一点。 问题答案: ES2015及更高版本 在ES2015中, 参数解构可用于模拟命名参数。这将要求调用者传递一个对象,但是如果您还使用默认参数,则可以避免函数内部的所有检查: ES5 有一种方法可以接近您想要

    • 我是angular和jhipster的新手,我已经编辑了登录组件,添加了formbuilder和MatDialogRef,并更新了单元测试:

    • 我有以下问题 我有一个带有随机名称的测试,我必须记录我从数据提供者提供的两个测试参数。 我实现了一种方法,通过将它们连接到名称中,将它们记录为自定义处理的测试参数。 然而,TestNG还添加了未处理的参数(它们看起来像是随机生成的代码,带有包/类的名称和其他内容,如下图所示)。 是否有任何方法可以删除TestNG记录的数据提供程序测试参数?或者我可以用自定义数据提供程序测试参数覆盖它们吗? 顺便说

    • 我想在TestNg中并行运行硒测试,使用“数据提供者”。理想情况下,测试是按方法并行的(一个测试=一个方法),而不是简单的浏览器套件并行。我在某个地方读到过,一次可以控制大约5个ChromeDriver实例,所以我认为这应该是可能的。稍后,我计划转移到grid2。对于开发,我将通过右键单击XML配置文件上的运行来运行IntelliJ idea测试运行程序。 我在并行运行测试时遇到了问题(在grid

    • 目前,我有一个测试类,它有多个方法,所有方法都使用相同的数据提供程序。每次testng循环使用不同的方法时,它都会重新计算数据提供程序方法。有没有办法让数据提供程序运行一次? 谢谢 杰森