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