问题描述
限时送ChatGPT账号..具有以下示例代码......在运行测试(和报告)时,我希望将测试名称设置为提供者提供的描述字段(实际上它是任何字符串).
...但是,即使从 ITest 扩展,似乎所有提供程序参数都附加到 TestName,我想要的只是描述.
所以实际的测试名称应该是 "TestName1" 而不是 "TestName2[1](TestName2, 2, 2, 4)" .. 这是 XML 报告中显示的内容,以及 test.aftertest 名称.
import org.testng.Assert;导入 org.testng.ITest;导入 org.testng.annotations.BeforeMethod;导入 org.testng.annotations.DataProvider;导入 org.testng.annotations.Test;导入 java.lang.reflect.Method;公共类 TestNgProviderExample 实现 ITest{@Test(dataProvider = "summationProvider")public void testProvider(String description, int number1, int number2, int sum) {Assert.assertEquals(sum, number1 + number2);}@DataProvider(name = "summationProvider")公共对象[][] summationData() {Object[][] testData = {{"TestName1",1,2,3},{"TestName2",2,2,4}};返回测试数据;}私人字符串报告测试名称 = "";@BeforeMethod(alwaysRun = true)public void testData(Method method, Object[] testData) {reportTestName = testData[0].toString();}@覆盖公共字符串 getTestName() {返回报告的测试名称;}}
解决方案 只需运行一个@Test
-注解不带参数的方法即可解决.
我的解决方案没有使用参数,而是使用类字段和构造函数 @Factory
方法.
public class TestClass 实现 ITest {受保护的字符串描述;受保护的 int firstNumber;受保护的 int secondNumber;受保护的整数总和;@测试公共无效测试提供者(){/*** 减号或加号在这里使它失败或通过.*/assertEquals(this.sum, this.firstNumber - this.secondNumber);}@Factory(dataProvider = "summationProvider")公共测试类(字符串描述,int firstNumber, int secondNumber, int sum) {this.description = 描述;this.firstNumber = firstNumber;this.secondNumber = secondNumber;this.sum = 总和;}@DataProvider(name = "summationProvider")公共静态对象[][] summationData() {Object[][] testData = {{"TestName1", 1, 2, 3}, {"TestName2", 2, 2, 4}};返回测试数据;}@覆盖公共字符串 getTestName() {返回 this.description;}}
从我的 IntelliJ Idea 输出格式:
当然,可以让 @Factory
实例化另一个类,而不是同一个 TestClass
.
如果您有 40 个独立的参数变量并希望保持简短...添加一个类作为这些参数的持有者,例如参数化输入
.它至少可以隐藏所有这些实例变量.您也可以将 description
放在第二个类中(在这种情况下,建议使用 ThreadLocal
使用).
第二个类将随着参数增长,但由于它是一个普通的旧 Java 对象,它不应该在测试中破坏任何东西.如果您不想设置所有这些变量,另一个想法是在测试中延迟访问参数.按照专家 (
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).
... 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.
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.
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.
Instead of parameters my solution uses class fields and a constructor @Factory
method.
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:
Of course, it is possible to make the @Factory
instantiate another class, not the same 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, e.g. 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).
The second class will grow with parameters, but since it is a plain old Java object, it shouldn't break anything in test.
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.
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:
这篇关于使用提供程序时覆盖 TestNG 测试名称并省略参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论