Override TestNG Test name when using provider and omit parameters

You have the following code example ... when running tests (and in reports), I would like the test names to be set in the vendor-supplied description field (actually any string).

... however, even when extended from ITest, it looks like all vendor parameters are appended to TestName, I only want a description.

So the actual test name should be "TestName1" instead of "TestName2 [1] (TestName2, 2, 2, 4)". This is what appears in XML reports and the name is 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;
    }
}

      

+1


source to share


1 answer


A simple execution of the @Test

-name method with no parameters can solve it.
Instead of parameters, my solution uses class fields and a constructor 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;
    }
}

      

Formatting output from my IntelliJ idea: enter image description here

Of course, it is possible to @Factory

instantiate a class other than the same one TestClass

.

And if you have 40 separate variables from parameters and want to keep them short ... Add a class that will hold these parameters, for example. ParametrizedInput

... This would at least hide all of those instance variables. You can place description

in the second class (in this case it is recommended to use ThreadLocal<ParametrizedInput>

).
The second class will grow with parameters, but since it is a plain old Java object, it shouldn't break anything in the test. If you don't want to set all of these variables, another idea would be to lazily access parameters in tests. After consulting an expert ( Krishnan Mahadevan ), I realized that a name using a method can be set using the @BeforeMethod

- and @AfterMethod

-annotated methods.



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 Type:

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:
enter image description here

+2


source







All Articles