TestNG 测试可以作为 DataProvider 吗?
Can TestNG tests serve as DataProviders?
我的项目中有成对的测试,我想在不同的方法中按顺序 运行。通常我会使用 DataProvider 来生成测试输入:
@DataProvider
public Object[][] getUsers() {
// generate input for test2();
}
@Test(dataProvider = "getUsers")
public void test2(User user) {
assertSomething(user);
}
但是在这里我需要这两种方法来像测试一样工作,因为我有测试逻辑,它不属于数据提供者。
所以我想要这样的东西:
@Test
public Object test1() {
User user = createUser();
assertSomething(user);
return user.getProperty();
}
@Test // depends on test1 - I do not want to execute this test if test1 fails.
public void test2(Object userProperty) {
assertSomethingElse(userProperty);
}
事实上,我可以将 test1 的逻辑放到 test2 中来实现我想要的,但我想知道是否有更智能的方法来做到这一点。
您要求的是状态测试class,TestNG 对此没有任何特定支持(例如,将数据从一个测试传递到另一个测试)。因此,您需要自己跟踪事物的状态。
如果您不担心并行性,那么 class 成员字段可以正常工作:
private User user;
@Test
public void test1() {
user = createUser();
assertSomething(user);
}
@Test(dependsOnMethods = "test1")
public void test2() {
assertSomethingElse(user.getProperty());
}
如果您确实希望能够 运行 并行测试 class 的多个实例,那么您需要使用类似 ThreadLocal<T>
:
private static final ThreadLocal<User> USERS = new InheritableThreadLocal<>();
@Test
public void test1() {
USERS.set(createUser());
assertSomething(user);
}
@Test(dependsOnMethods = "test1")
public void test2() {
assertSomethingElse(USERS.get().getProperty());
}
是的,有办法。我想这就是你想要的。与 JUnit 不同,TestNG 允许您在测试方法运行之前挂钩并访问测试方法的参数,有点像您可以使用 AOP 做的:
@DataProvider
public Object[][] getUsers() {
int[][] multi = new int[][]{
{ 0, new User("Tom") },
{ 0, new User("Sally") }
};
return multi;
}
@BeforeMethod
public void setupBeforeEachTest(Object[] args) {
User x = (User)args[1];
x.modify();
}
@Test(dataProvider = "getUsers")
public void test1(User user) {
assertSomething(user);
}
@Test(dataProvider = "getUsers")
public void test2(User user) {
assertSomethingElse(user);
}
这是一个解决方案,无论您是否 运行 并行使用其他套件。dependsOnMethods 参数将确保 test2 运行s 在测试 1 passes.The 之后的想法是实施工厂:
您的测试方法将如下所示:
@Test
public void test1(ITestContext context) {
User objUser = Factory.getUser(context.getName());
assertSomething(objUser);
}
@Test(dependsOnMethods = "test1")
public void test2(ITestContext context) { assertSomethingElse(Factory.getUser(context.getName()).getProperty());
}
工厂 class 将类似于:
public class Factory
{
static Map<testName,User> mainMap;
//This method returns User object to a test based on the test name.
public static User getUser(String testName)
{
if (mainMap == null)
{
mainMap = new HashTable<testName,User>();
mainMap.put(testName,new User());
}
if(!mainMap.contains(testName))
{
mainMap.put(testName,new User());
}
return mainMap.get(testName);
}
}
有关使用工厂在方法/线程之间共享对象背后理论的更多信息,请参阅以下内容:
http://singinginthesunlight.blogspot.in/2016/02/testng-parallelism-kiss-of-death-or.html
我的项目中有成对的测试,我想在不同的方法中按顺序 运行。通常我会使用 DataProvider 来生成测试输入:
@DataProvider
public Object[][] getUsers() {
// generate input for test2();
}
@Test(dataProvider = "getUsers")
public void test2(User user) {
assertSomething(user);
}
但是在这里我需要这两种方法来像测试一样工作,因为我有测试逻辑,它不属于数据提供者。
所以我想要这样的东西:
@Test
public Object test1() {
User user = createUser();
assertSomething(user);
return user.getProperty();
}
@Test // depends on test1 - I do not want to execute this test if test1 fails.
public void test2(Object userProperty) {
assertSomethingElse(userProperty);
}
事实上,我可以将 test1 的逻辑放到 test2 中来实现我想要的,但我想知道是否有更智能的方法来做到这一点。
您要求的是状态测试class,TestNG 对此没有任何特定支持(例如,将数据从一个测试传递到另一个测试)。因此,您需要自己跟踪事物的状态。
如果您不担心并行性,那么 class 成员字段可以正常工作:
private User user;
@Test
public void test1() {
user = createUser();
assertSomething(user);
}
@Test(dependsOnMethods = "test1")
public void test2() {
assertSomethingElse(user.getProperty());
}
如果您确实希望能够 运行 并行测试 class 的多个实例,那么您需要使用类似 ThreadLocal<T>
:
private static final ThreadLocal<User> USERS = new InheritableThreadLocal<>();
@Test
public void test1() {
USERS.set(createUser());
assertSomething(user);
}
@Test(dependsOnMethods = "test1")
public void test2() {
assertSomethingElse(USERS.get().getProperty());
}
是的,有办法。我想这就是你想要的。与 JUnit 不同,TestNG 允许您在测试方法运行之前挂钩并访问测试方法的参数,有点像您可以使用 AOP 做的:
@DataProvider
public Object[][] getUsers() {
int[][] multi = new int[][]{
{ 0, new User("Tom") },
{ 0, new User("Sally") }
};
return multi;
}
@BeforeMethod
public void setupBeforeEachTest(Object[] args) {
User x = (User)args[1];
x.modify();
}
@Test(dataProvider = "getUsers")
public void test1(User user) {
assertSomething(user);
}
@Test(dataProvider = "getUsers")
public void test2(User user) {
assertSomethingElse(user);
}
这是一个解决方案,无论您是否 运行 并行使用其他套件。dependsOnMethods 参数将确保 test2 运行s 在测试 1 passes.The 之后的想法是实施工厂:
您的测试方法将如下所示:
@Test
public void test1(ITestContext context) {
User objUser = Factory.getUser(context.getName());
assertSomething(objUser);
}
@Test(dependsOnMethods = "test1")
public void test2(ITestContext context) { assertSomethingElse(Factory.getUser(context.getName()).getProperty());
}
工厂 class 将类似于:
public class Factory
{
static Map<testName,User> mainMap;
//This method returns User object to a test based on the test name.
public static User getUser(String testName)
{
if (mainMap == null)
{
mainMap = new HashTable<testName,User>();
mainMap.put(testName,new User());
}
if(!mainMap.contains(testName))
{
mainMap.put(testName,new User());
}
return mainMap.get(testName);
}
}
有关使用工厂在方法/线程之间共享对象背后理论的更多信息,请参阅以下内容: http://singinginthesunlight.blogspot.in/2016/02/testng-parallelism-kiss-of-death-or.html