我发现您可以使用ITestContext或java.lang.reflect.Method声明数据提供程序。作为参数,但我想知道调用dataprovider方法的测试类的类名。 ITestContext和java.lang.reflect.Method都不能提供该功能。
method.getDeclaringClass()应该在dataprovider方法中为您提供方法的类名。
这里是我的问题的answer。如果有人有更好的答案,请告诉我。
解决方案是数据提供者不能接受任意输入,但是他们可以接受对当前测试方法的引用。因此,我们可以创建一个新的注释DataProviderArguments,可以将其附加到测试方法,然后在参数中传递类名。
创建注释
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotation for feeding arguments to methods conforming to the
* "@DataProvider" annotation type.
* @author jharen
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface DataProviderArguments
{
/**
* String array of key-value pairs fed to a dynamic data provider.
* Should be in the form of key=value, e.g., <br />
* args={"foo=bar", "biz=baz"}
*/
String[] value();
}
创建一个帮助程序类,它将读取参数并将其传递给。
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class DataProviderUtils
{
protected static Map<String, String> resolveDataProviderArguments(Method testMethod) throws Exception
{
if (testMethod == null)
throw new IllegalArgumentException("Test Method context cannot be null.");
DataProviderArguments args = testMethod.getAnnotation(DataProviderArguments.class);
if (args == null)
throw new IllegalArgumentException("Test Method context has no DataProviderArguments annotation.");
if (args.value() == null || args.value().length == 0)
throw new IllegalArgumentException("Test Method context has a malformed DataProviderArguments annotation.");
Map<String, String> arguments = new HashMap<String, String>();
for (int i = 0; i < args.value().length; i++)
{
String[] parts = args.value()[i].split("=");
arguments.put(parts[0], parts[1]);
}
return arguments;
}
并且,FileDataProvider可以读取任何给定的文件:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.testng.annotations.DataProvider;
public class FileDataProvider
{
@DataProvider(name="getDataFromFile")
public static Iterator<Object[]> getDataFromFile(Method testMethod) throws Exception
{
Map<String, String> arguments = DataProviderUtils.resolveDataProviderArguments(testMethod);
List<String> lines = FileDataProvider.getRawLinesFromFile(arguments.get("filePath"));
List<Object[]> data = new ArrayList<Object[]>();
for (String line : lines)
{
data.add(new Object[]{line});
}
return data.iterator();
}
public static List<String> getRawLinesFromFile(Method testMethod) throws Exception
{
Map<String, String> arguments = DataProviderUtils.resolveDataProviderArguments(testMethod);
return FileDataProvider.getRawLinesFromFile(arguments.get("filePath"));
}
@SuppressWarnings("unchecked")
public static List<String> getRawLinesFromFile(String filePath) throws Exception
{
InputStream is = new FileInputStream(new File(filePath));
List<String> lines = IOUtils.readLines(is, "UTF-8");
is.close();
return lines;
}
}
最后编写这样的测试;
@Test(dataProviderClass=com.netflix.systemtests.api.commons.dataproviders.TestAccountDataProvider.class, dataProvider="getTestAccountsFromFile")
@DataProviderArguments("filePath=src/main/resources/input-files/testAccounts.txt")
public void fetchInstantQueueAsJSON(String email, String accountID) throws Exception
{
// blah blah blah testy test goes here
}
您需要将ITestNGMethod对象作为参数传递给@DataProvider方法。通过它您应该能够提取出所需的内容。
这里是一个样本
public static Object[][] dataProvider(ITestNGMethod method) {
Class cla = method.getRealClass();
Method tm = method.getConstructorOrMethod().getMethod();
Constructor constructor = method.getConstructorOrMethod().getConstructor();
String name = cla.getName() + ".";
if (tm == null) {
name = constructor.getName();
} else {
name = name + tm.getName();
}
System.out.println("Data provider is being called by " + name);