如何 运行 使用来自 Excel 的数据进行条件 TestNG 测试
How to run conditional TestNG Tests with data from Excel
我有一个 class,其中包含多个 @Test 方法,每个方法具有不同的功能。
class myTests
{
@Test
test1()
{
...............
}
@Test
test2()
{
...............
}
}
我正在遵循数据驱动方法,我在 Excel 中拥有数据。 excel sheet 中的每一行对应一个不同的测试用例,应该执行上面 class.
中的测试方法
下面是来自 excel sheet 的示例数据,其中包含作为参数之一的方法名称(例如:test1、test2)以及一个确定是否应选择案例的标志在 运行 时间执行或不执行(例如:y,n)
case1 data1 data2 data3........test1 y
case2 data4 data5 data6........test1 y
case3 data7 data8 data9........test2 y
case4 data10 data11 data12........test1 n
以下是我的问题:
- 如何将案例映射到相应的测试方法
- 具体情况如何运行根据flag
我的理解是,使用 DataProvider 注释,测试方法可以 运行 使用不同的输入数据。但是如果单个 class 中有多个测试方法,我不确定如何将测试方法与相应的测试数据映射。
我还尝试寻找可用于改变测试方法的 运行 时间行为的 IAnnotationTransformer,但找不到将标志数据从 excel 发送到转换器 class.
提前致谢..
关于如何做到这一点,有一些细节,您可以做到,但它需要您进行大量自定义。 TestNG 中没有任何东西可以为您提供开箱即用的这种功能。
IAnnotationTransformer
不会帮助你,因为这个侦听器只考虑方法而不知道实例。它也在任何 运行s 之前 运行s 并且您无法在其中进行此迭代。这样就可以排除了。
您最好的选择是使用 @Factory
和 @DataProvider
,其中 @Factory
将产生 ONLY 一个测试实例class 并且您所有的测试方法都必须强制成为同一测试的一部分 class。
想法是这样的:
- 在您的数据源中创建一个额外的列,代表 class 基本上应该使用数据源。
- 构建一个数据提供者,它读取上述数据源,过滤掉完全限定 class 名称与当前数据提供者的封闭 class.[=38= 匹配的所有行]
- 还应该构建数据提供程序,以便它创建一个映射(键是测试方法名称,值是要用于不同迭代的值列表)。
- 一旦它拥有所有过滤的行,它只创建一行测试数据,这样,TestNG 只创建一个测试 class 实例。
- 让你的测试 class 也实现
IHookable
接口,这样你就可以决定哪个测试方法 运行 以及哪个可以跳过。
- 现在,如果一个方法满足 运行 的检查,您将基本上让测试方法循环遍历它拥有的所有测试数据(因此它始终有 1 个测试方法将 运行循环处理所有数据,这与 TestNG 自动为您执行的数据提供程序设置不同),并且您诉诸于使用软断言来断言所有验证。这样,在完成所有迭代后,您的测试将 pass/fail 。
这是一个示例,展示了其中的一些实际操作。
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestclassSample implements IHookable {
private List<String> methodsToRun = new ArrayList<>();
@Factory(dataProvider = "dp")
public TestclassSample(List<String> methodsToRun) {
this.methodsToRun = methodsToRun;
}
@Override
public void run(IHookCallBack callBack, ITestResult testResult) {
String testMethodName = testResult.getMethod().getMethodName();
if (methodsToRun.contains(testMethodName)) {
System.err.println("About to run " + testResult.getMethod().getMethodName());
callBack.runTestMethod(testResult);
} else {
testResult.setStatus(ITestResult.SKIP);
}
}
@Test
public void testMethod() {
System.err.println("testMethod()");
}
@Test
public void anotherTestMethod() {
System.err.println("anotherTestMethod()");
}
@Test
public void thirdTestMethod() {
System.err.println("thirdTestMethod()");
}
@DataProvider(name = "dp")
public static Object[][] getData() {
return new Object[][]{
{Arrays.asList("testMethod", "thirdTestMethod")}
};
}
}
这是输出:
About to run testMethod
testMethod()
About to run thirdTestMethod
thirdTestMethod()
Test ignored.
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 1
===============================================
我有一个 class,其中包含多个 @Test 方法,每个方法具有不同的功能。
class myTests
{
@Test
test1()
{
...............
}
@Test
test2()
{
...............
}
}
我正在遵循数据驱动方法,我在 Excel 中拥有数据。 excel sheet 中的每一行对应一个不同的测试用例,应该执行上面 class.
中的测试方法下面是来自 excel sheet 的示例数据,其中包含作为参数之一的方法名称(例如:test1、test2)以及一个确定是否应选择案例的标志在 运行 时间执行或不执行(例如:y,n)
case1 data1 data2 data3........test1 y
case2 data4 data5 data6........test1 y
case3 data7 data8 data9........test2 y
case4 data10 data11 data12........test1 n
以下是我的问题:
- 如何将案例映射到相应的测试方法
- 具体情况如何运行根据flag
我的理解是,使用 DataProvider 注释,测试方法可以 运行 使用不同的输入数据。但是如果单个 class 中有多个测试方法,我不确定如何将测试方法与相应的测试数据映射。
我还尝试寻找可用于改变测试方法的 运行 时间行为的 IAnnotationTransformer,但找不到将标志数据从 excel 发送到转换器 class.
提前致谢..
关于如何做到这一点,有一些细节,您可以做到,但它需要您进行大量自定义。 TestNG 中没有任何东西可以为您提供开箱即用的这种功能。
IAnnotationTransformer
不会帮助你,因为这个侦听器只考虑方法而不知道实例。它也在任何 运行s 之前 运行s 并且您无法在其中进行此迭代。这样就可以排除了。
您最好的选择是使用 @Factory
和 @DataProvider
,其中 @Factory
将产生 ONLY 一个测试实例class 并且您所有的测试方法都必须强制成为同一测试的一部分 class。
想法是这样的:
- 在您的数据源中创建一个额外的列,代表 class 基本上应该使用数据源。
- 构建一个数据提供者,它读取上述数据源,过滤掉完全限定 class 名称与当前数据提供者的封闭 class.[=38= 匹配的所有行]
- 还应该构建数据提供程序,以便它创建一个映射(键是测试方法名称,值是要用于不同迭代的值列表)。
- 一旦它拥有所有过滤的行,它只创建一行测试数据,这样,TestNG 只创建一个测试 class 实例。
- 让你的测试 class 也实现
IHookable
接口,这样你就可以决定哪个测试方法 运行 以及哪个可以跳过。 - 现在,如果一个方法满足 运行 的检查,您将基本上让测试方法循环遍历它拥有的所有测试数据(因此它始终有 1 个测试方法将 运行循环处理所有数据,这与 TestNG 自动为您执行的数据提供程序设置不同),并且您诉诸于使用软断言来断言所有验证。这样,在完成所有迭代后,您的测试将 pass/fail 。
这是一个示例,展示了其中的一些实际操作。
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestclassSample implements IHookable {
private List<String> methodsToRun = new ArrayList<>();
@Factory(dataProvider = "dp")
public TestclassSample(List<String> methodsToRun) {
this.methodsToRun = methodsToRun;
}
@Override
public void run(IHookCallBack callBack, ITestResult testResult) {
String testMethodName = testResult.getMethod().getMethodName();
if (methodsToRun.contains(testMethodName)) {
System.err.println("About to run " + testResult.getMethod().getMethodName());
callBack.runTestMethod(testResult);
} else {
testResult.setStatus(ITestResult.SKIP);
}
}
@Test
public void testMethod() {
System.err.println("testMethod()");
}
@Test
public void anotherTestMethod() {
System.err.println("anotherTestMethod()");
}
@Test
public void thirdTestMethod() {
System.err.println("thirdTestMethod()");
}
@DataProvider(name = "dp")
public static Object[][] getData() {
return new Object[][]{
{Arrays.asList("testMethod", "thirdTestMethod")}
};
}
}
这是输出:
About to run testMethod
testMethod()
About to run thirdTestMethod
thirdTestMethod()
Test ignored.
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 1
===============================================