简体   繁体   English

使用提供程序时覆盖TestNG测试名称并忽略参数

[英]Override TestNG Test name when using a provider and omit parameters

Have the following Sample code ... when running tests (and in reports), I would like the Test Names to be set to the description field provided by the provider (really it's any String). 具有以下示例代码...在运行测试(以及在报告中)时,我希望将“测试名称”设置为提供程序提供的描述字段(实际上是任何String)。

... however, even when extending from ITest, it seems like all the provider parameters get appended to the TestName, what I want is the description only. ...但是,即使从ITest扩展,似乎所有提供程序参数都附加到了TestName之后,我想要的只是描述。

So actual test name should be "TestName1" instead of "TestName2[1](TestName2, 2, 2, 4)" .. which is what is showing up in XML reports, and test.aftertest name. 因此,实际的测试名称应为“ TestName1”,而不是“ TestName2 [1](TestName2,2,2,4)” .. XML报告中显示的名称以及test.aftertest名称。

import org.testng.Assert;
import org.testng.ITest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.lang.reflect.Method;

public class TestNgProviderExample implements ITest{

    @Test(dataProvider = "summationProvider")
    public void testProvider(String description, int number1, int number2, int sum) {
        Assert.assertEquals(sum, number1 + number2);
    }

    @DataProvider(name = "summationProvider")
    public Object[][] summationData() {
        Object[][] testData = {{"TestName1",1,2,3},{"TestName2",2,2,4}};
        return testData;
    }

    private String reportedTestName = "";

    @BeforeMethod(alwaysRun = true)
    public void testData(Method method, Object[] testData) {
        reportedTestName = testData[0].toString();
    }

    @Override
    public String getTestName() {
        return reportedTestName;
    }
}

Simply running a @Test -annotated method without parameters can solve it. 只需运行不带参数的@Test注释方法即可解决该问题。
Instead of parameters my solution uses class fields and a constructor @Factory method. 我的解决方案不是使用参数,而是使用类字段和构造函数@Factory方法。

public class TestClass implements ITest {

    protected String description;
    protected int firstNumber;
    protected int secondNumber;
    protected int sum;

    @Test
    public void testProvider() {
        /**
         * Minus or plus here to make it fail or pass.
         */
        assertEquals(this.sum, this.firstNumber - this.secondNumber);
    }

    @Factory(dataProvider = "summationProvider")
    public TestClass(String description,
                     int firstNumber, int secondNumber, int sum) {
        this.description = description;
        this.firstNumber = firstNumber;
        this.secondNumber = secondNumber;
        this.sum = sum;
    }

    @DataProvider(name = "summationProvider")
    public static Object[][] summationData() {
        Object[][] testData = {{"TestName1", 1, 2, 3}, {"TestName2", 2, 2, 4}};
        return testData;
    }

    @Override
    public String getTestName() {
        return this.description;
    }
}

Output with formatting from my IntelliJ Idea: 从我的IntelliJ Idea格式化输出: 在此处输入图片说明

Of course, it is possible to make the @Factory instantiate another class, not the same TestClass . 当然,可以使@Factory实例化另一个类,而不是相同的TestClass

And if you have 40 separate variables from parameters and want to keep it short... Add a class that would be a holder for those parameters, eg ParametrizedInput . 而且,如果您有40个与参数分开的变量,并希望使其简短,则...添加一个将成为这些参数的持有人的类,例如ParametrizedInput It would at least make it possible to hide all those instance variables. 至少可以隐藏所有这些实例变量。 You can place description in the second class as well (in that case ThreadLocal<ParametrizedInput> usage would be advised). 您也可以在第二个类中放置description (在这种情况下,建议使用ThreadLocal<ParametrizedInput> )。
The second class will grow with parameters, but since it is a plain old Java object, it shouldn't break anything in test. 第二个类将随着参数增长,但是由于它是一个普通的旧Java对象,因此它在测试中不会破坏任何内容。 If you don't want to set all those variables, another idea would be to access parameters lazily in tests. 如果您不想设置所有这些变量,则另一个想法是在测试中延迟访问参数。 Following expert's ( Krishnan Mahadevan ) advice I figured out that the name with a method can be set with a @BeforeMethod - and @AfterMethod -annotated methods. 遵循专家( Krishnan Mahadevan )的建议,我发现可以使用@BeforeMethod@AfterMethod方法设置带有方法的名称。

public class TestClass implements ITest {

    protected static ThreadLocal<String> description
            = new ThreadLocal<>();
    protected ParametrizedInput input;

    @BeforeMethod
    public void setUp(Method method) {
        this.description.set(this.description.get() + " " + method.getName());
    }

    @AfterMethod
    public void tearDown(Method method) {
        this.description.set(this.description.get().substring(0,
                this.description.get().length() - method.getName().length()));
    }

    @Test
    public void testProvider() {
        assertEquals(this.input.getSum(),
                this.input.getFirstNumber() / this.input.getSecondNumber());
    }

    @Test
    public void anotherTestProvider() {
        assertEquals(this.input.getSum(),
                this.input.getFirstNumber() - this.input.getSecondNumber());
    }
    @Factory(dataProvider = "summationProvider")
    public TestClass(String descriptionString, ParametrizedInput input) {
        this.description.set(descriptionString);
        this.input = input;
    }

    @DataProvider(name = "summationProvider")
    public static Object[][] summationData() {
        Object[][] testData = {{"TestName1", new ParametrizedInput(1, 2, 3)},
                {"TestName2", new ParametrizedInput(2, 2, 4)}};
        return testData;
    }

    @Override
    public String getTestName() {
        return this.description.get();
    }
}

Parameter Holder class: 参数持有人类别:

public class ParametrizedInput {

    private int firstNumber;
    private int secondNumber;
    private int sum;

    public ParametrizedInput(int firstNumber,
                             int secondNumber, int sum) {
        this.firstNumber = firstNumber;
        this.secondNumber = secondNumber;
        this.sum = sum;
    }

    public int getFirstNumber() {
        return firstNumber;
    }

    public int getSecondNumber() {
        return secondNumber;
    }

    public int getSum() {
        return sum;
    }
}

Result: 结果:
在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用参数时,Testng会忽略@Test - Testng ignores @Test, when parameters are used 获取和使用 TestNG @test 注解参数 - getting and using TestNG @test annotation parameters TestNg 当数据输入提供者是 CSV 文件时打印参数的值 - TestNg Printing the value of the parameters when the data input provider is a CSV file 如何获取测试用例描述/在for循环中执行测试用例时,使用testNG使用测试用例的名称 - How to get Test case Description / Name of test case using testNG when testcases are executing in for loop 使用 testNG 将测试中的数据提供者元素用作数组 - Exploitation of data provider elements inside test as array, using testNG 有没有一种方法可以将参数传递给TestNG测试,而无需在XML中使用@DataProvider和参数? - Is there a way to pass parameters to TestNG test without using @DataProvider & parameters in XML? 在 TestNG 上检索测试名称 - Retrieve test name on TestNG TestNg DataBinding:无法传递参数以使用数据绑定进行测试 - TestNg DataBinding : unable to pass parameters to test using databinding 如何使用org.testng.TestNG将参数输入此测试运行中? - How can I get parameters into this test run using org.testng.TestNG? 使用IntelliJ运行单独的testng测试并读取testng.xml参数 - Run individual testng test and read testng.xml parameters using IntelliJ
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM