TestNG @Factory Priority

时间:2016-08-12 20:51:43

标签: java automated-tests testng

有没有办法优先考虑@Factory方法?我已尝试@AfterMethod@AfterTest@AfterClass,我的工厂方法在使用@BeforeClass代码进行设置调用后立即运行。

我的代码与此类似:

    @BeforeClass
    public void setup() {

    }

    @Test()
    public void method1() throws Exception {

    }

    @Test(dependsOnMethods = "method1")
    public void method2() {

    }

    @Test(dependsOnMethods = "method2")
    public void method3() throws Exception {

    }

    @Test(dependsOnMethods = "method3")
    public void method4() throws Exception {

    }

    @Test(dependsOnMethods = "method4")
    public void method5() throws Exception {

    }

    @AfterClass
    @Factory
    public Object[] factory() {
        Object[] values = new Object[10];
        for (int i = 0; i < values.length; i++) {
            values[i] = new validationFactory(map.get(i).x, map.get(i).y);
        }
        return values;
    }

代码正在做的是接触API,检索任何请求的数据,将数据切分为map,然后将该数据映射传递到工厂方法以验证它。问题是,在我的设置方法运行后,工厂立即射击并验证空地图。有没有办法让工厂方法等到数据就绪?

2 个答案:

答案 0 :(得分:1)

@Factory的目的是create tests dynamically。在@AfterClass方法之后运行这些测试是没有意义的,所以即使你可以通过检查地图是否为空来解决问题(以便factory()运行两次,但循环 - 只有一次),工厂创建的任何测试都不会被框架执行。

如果您需要在所有测试完成后验证某些数据,请将该验证放在使用@AfterClass注释的方法中(不含@Factory)。您可以在常规测试中使用断言。

如果出于某种原因,您希望将验证作为单独的测试运行并且必须使用工厂,则有一种方法可以将其执行推迟到其他测试之后,但它们仍然必须在开始时进行实例化。因此,看起来您需要传递一些在需要时加载数据的对象,而不是立即使用地图条目初始化验证测试。数据提供者可以工作,但这是一个更简单的例子。

将所有主要测试添加到组中。

@Test(dependsOnMethods = "method1", groups = "Main")
public void method2() { }

创建一个将在需要时加载数据的类或方法,它取决于您填充地图的方式。它必须是线程安全的,因为TestNG并行运行测试。一个非常简单的实现:

public class DataLoader {

    // Location has data members X and Y
    private Map<Integer, Location> locations;

    public synchronized Location getLocation(int index) {

        if (locations == null) {
            locations = new HashMap<>();
            // load the map
        }

        return locations.get(index);
    }
}

创建一个表示验证测试的类。请注意,它的唯一测试取决于主要组。

public class ValidationTest {

    private int index;
    private DataLoader loader;

    public ValidationTest(int index, DataLoader loader) {
        this.number = number;
        this.loader = loader;
    }

    @Test(dependsOnGroups = "Main")
    public void validate() {
        Location location = this.loader.getLocation(this.index);
        // do whatever with location.x and location.y
    }
}

实例化验证测试。它们将在主要组完成后运行。请注意,我已删除了@AfterClass注释。

@Factory
public Object[] factory() {

    DataLoader loader = new DataLoader();
    Object[] validators = new Object[10];
    for (int i = 0; i < validators.length; i++) {
        validators[i] = new ValidationTest(i, loader);
    }

    return validators;
}

顺便说一句,测试方法之间的依赖关系表明编写不好的测试,应该避免,至少对于单元测试。除了TestNG之外,还有用于测试复杂场景的框架。

答案 1 :(得分:0)

TestNG运行有两个不同的阶段:

  1. 创建测试;
  2. 运行测试。
  3. 然后,您可以期望在测试运行期间创建一些新测试。