如何从 TestNG 数据提供者名称获取数据提供者方法? [英] How to get data provider method from TestNG data provider name?
问题描述
有谁知道TestNG如何根据为测试方法指定的数据提供者名称找出数据提供者方法是什么?
Does anyone know how TestNG figures out what the data provider method is based on the data provider name specified for a test method?
我找到了这个解决方案:https://gist.github.com/ae6rt/3805639
I found this solution: https://gist.github.com/ae6rt/3805639
但是,它没有考虑到数据提供者可能是:
However, it doesn't take into account that the data provider could be:
- 在一个完全不同的类中定义,或
- 在父类中定义,并且
- 该方法可以是静态的,也可以是非静态的.
我试图自己破解一些东西,但后来我发现我不可能是第一个尝试解决问题的人,尤其是因为显然 TestNG 必须有解决方案.
I tried to hack something together on my own, but then I figured that I can't possibly be the first person to try to solve the problem, especially because obviously TestNG must have a solution to that.
有谁知道 TestNG 是如何做到的,以及如何访问该业务逻辑?
Does anyone know how TestNG does it, and how to get access to that business logic?
我正在尝试计算启动时的总测试计数",如下所述:如何在 TestNG 开始时获取测试总量(包括考虑数据提供者)?
I'm trying to figure out the "total test count" at start up as discussed here: How to get total amount of tests (incl. taking data providers into account) at TestNG start?
推荐答案
这可能是一个很晚的答案,但仍将其发布.
This might be a very late answer, but still posting it.
以下示例展示了如何使用 TestNG 来完成.我正在使用 TestNG 7.0.0-beta1
(截至今天的最新发布版本).
The below samples show how it can be done using TestNG. I am using TestNG 7.0.0-beta1
(latest released version as of today).
场景 1:数据提供者位于同一个类中.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(DataProviderTrackingListener.class)
public class DataProviderInSameClass {
@Test(dataProvider = "dp")
public void testMethod(int i) {
System.err.println(i);
}
@DataProvider(name = "dp")
public Object[][] getData() {
return new Object[][] {{1}, {2}};
}
}
场景 2:数据提供者驻留在基类中.
import org.testng.annotations.DataProvider;
public class BaseClass {
@DataProvider(name = "dp")
public Object[][] getData() {
return new Object[][] {{1}, {2}};
}
}
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(DataProviderTrackingListener.class)
public class DataProviderInBaseClass extends BaseClass {
@Test(dataProvider = "dp")
public void testMethod(int i) {
System.err.println(i);
}
}
场景 3:数据提供者驻留在一个完全不同的类中.
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(DataProviderTrackingListener.class)
public class DataProviderInDifferentClass {
@Test(dataProvider = "dp", dataProviderClass = BaseClass.class)
public void testMethod(int i) {
System.err.println(i);
}
}
侦听器提取所有这些信息并将其显示给您
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderTrackingListener implements ITestListener {
@Override
public void onTestStart(ITestResult result) {
Test test = result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class);
if (test == null) {
return;
}
Method method = null;
Class<?> foundInClass = null;
if (isDataProviderPresentInDifferentClass(test)) {
method = extractDataProviderMethodFrom(test.dataProviderClass());
foundInClass = test.dataProviderClass();
} else {
Class<?> currentClass = result.getInstance().getClass();
while (currentClass != Object.class) {
Optional<Method> methods =
Arrays.stream(currentClass.getDeclaredMethods())
.filter(
eachMethod -> {
DataProvider dataProvider = eachMethod.getAnnotation(DataProvider.class);
return (dataProvider != null
&& dataProvider.name().equals(test.dataProvider()));
})
.findFirst();
if (methods.isPresent()) {
method = methods.get();
foundInClass = currentClass;
break;
}
currentClass = currentClass.getSuperclass();
}
}
if (method != null) {
String msg =
String.format(
"Data provider [%s] found in class [%s]", method.getName(), foundInClass.getName());
System.err.println(msg);
}
}
private static boolean isDataProviderPresentInDifferentClass(Test test) {
return test.dataProviderClass() != Object.class;
}
private static Method extractDataProviderMethodFrom(Class<?> clazz) {
Optional<Method> method =
Arrays.stream(clazz.getMethods())
.filter(eachMethod -> eachMethod.getAnnotation(DataProvider.class) != null)
.findFirst();
return method.orElse(null);
}
}
这篇关于如何从 TestNG 数据提供者名称获取数据提供者方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!