使用提供程序时覆盖 TestNG 测试名称并省略参数
Override TestNG Test name when using a provider and omit parameters
有以下示例代码...当 运行 测试时(以及在报告中),我希望将测试名称设置为提供者提供的描述字段(实际上是任何字符串)。
...然而,即使从 ITest 扩展时,似乎所有提供程序参数都附加到 TestName,我想要的只是描述。
所以实际的测试名称应该是 "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;
}
}
只需运行一个@Test
注解无参方法即可解决
我的解决方案使用 class 字段和构造函数 @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;
}
}
从我的 IntelliJ Idea 格式化输出:
当然可以让@Factory
实例化另一个class,不一样TestClass
.
如果您有 40 个独立的参数变量并希望保持简短...添加一个 class 作为这些参数的容器,例如ParametrizedInput
。它至少可以隐藏所有这些实例变量。
您也可以将 description
放在第二个 class 中(在这种情况下,建议使用 ThreadLocal<ParametrizedInput>
)。
第二个 class 将随参数增长,但由于它是一个普通的旧 Java 对象,它不应该在测试中破坏任何东西。
如果您不想设置所有这些变量,另一个想法是在测试中延迟访问参数。
按照专家 (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();
}
}
参数持有者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;
}
}
结果:
有以下示例代码...当 运行 测试时(以及在报告中),我希望将测试名称设置为提供者提供的描述字段(实际上是任何字符串)。
...然而,即使从 ITest 扩展时,似乎所有提供程序参数都附加到 TestName,我想要的只是描述。
所以实际的测试名称应该是 "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;
}
}
只需运行一个@Test
注解无参方法即可解决
我的解决方案使用 class 字段和构造函数 @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;
}
}
从我的 IntelliJ Idea 格式化输出:
当然可以让@Factory
实例化另一个class,不一样TestClass
.
如果您有 40 个独立的参数变量并希望保持简短...添加一个 class 作为这些参数的容器,例如ParametrizedInput
。它至少可以隐藏所有这些实例变量。
您也可以将 description
放在第二个 class 中(在这种情况下,建议使用 ThreadLocal<ParametrizedInput>
)。
第二个 class 将随参数增长,但由于它是一个普通的旧 Java 对象,它不应该在测试中破坏任何东西。
如果您不想设置所有这些变量,另一个想法是在测试中延迟访问参数。
按照专家 (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();
}
}
参数持有者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;
}
}
结果: