0

我的项目中有一对测试,我想以不同的方法顺序运行。通常我会使用 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 来实现我想要的,但我想知道是否有更智能的方法来做到这一点。

4

3 回答 3

1

是的,有办法。我认为这样的事情就是你想要的。与 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);
}
于 2016-02-26T17:00:10.913 回答
0

您要求的是一个有状态的测试类,TestNG 没有任何特定的支持(例如,将数据从一个测试传递到另一个测试)。因此,您需要自己跟踪事物的状态。

如果您不担心并行性,那么类成员字段可以正常工作:

private User user;

@Test
public void test1() {
    user = createUser();
    assertSomething(user);
}

@Test(dependsOnMethods = "test1")
public void test2() {
    assertSomethingElse(user.getProperty());
}

如果您确实希望能够并行运行测试类的多个实例,那么您需要使用类似的东西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());
}
于 2016-02-26T14:46:49.673 回答
0

这是一个无论您是否并行运行其他套件都可以工作的解决方案。dependsOnMethods 参数将确保 test2 在测试 1 通过后运行。这个想法是实现一个工厂:

您的测试方法将如下所示:

@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());
}

工厂类将类似于:

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

于 2016-02-27T11:13:47.777 回答