2016-08-12 68 views
1

有没有把优先级上一个@Factory法的方式进行?我试过@AfterMethod@AfterTest@AfterClass,所有的结果在我的工厂方法与@BeforeClass标签我建立呼叫后立即运行。TestNG的@Factory优先

我的代码是与此类似:

@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,然后通过该地图数据进入工厂方法以验证它。问题是,在我的设置方法运行后,工厂立即启动并验证空映射。有没有办法让工厂方法等待数据准备好?

回答

1

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

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

如果由于某种原因您想要将验证作为单独的测试运行并且必须使用工厂,那么有一种方法可以将其执行推迟到其他测试之后,但仍然必须在开始时进行实例化。所以看起来你需要传递一些会在需要时加载数据的对象,而不是马上用map条目初始化验证测试。数据提供者可能会工作,但这是一个更简单的例子。

添加的所有主要测试组。

@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以外,还有其他框架用于测试复杂场景。

+0

您的解决方案在我设置的小规模测试中完美工作,但您将如何扩大Object []的大小?因为它需要动态调整大小,因为我找回的数据可能是1或10,000个条目。至于依赖关系,如果您有关于如何改进它们的提示,那将不胜感激。现在,我不希望验证方法在有任何数据需要验证之前运行,并且我不希望在API向我发送文件/数据之前运行我的文件处理测试。 – user2434692

+1

我的解决方案是基于你的例子,其中'values'的大小是已知的。正如我告诉你的,动态测试可以在其余完成后运行,但它们必须在开始时初始化。使用最后运行的测试方法或'@ AfterClass'方法进行验证。在这种情况下工厂将无法工作。 – vempo

+0

感谢您的答案,我想我可以解决数组长度问题。 – user2434692

0

甲TestNG的运行有2个不同的阶段:

  1. 测试创作;
  2. 运行测试。

然后,你可以期望的测试在运行过程中创造出一些新的测试。