最近使用TestNG有一个需求,希望在配合使用factory执行测试时,factory生成测试数据的执行顺序与生成时保持一致。
在未做任何定制时,执行顺序是随机的,如果想要一致的顺序,就得额外配置拦截器:IMethodInterceptor
具体实现方法, 如下:
工厂类:
@Listeners(ExampleInterceptor.class) // 通过拦截器重新给方法排序, 否则是乱序的 public class FactoryTest_Order { @Factory public Object[] createInstance() { return new Object[]{ new TestData().setName("Zidane").setOrder(1), new TestData().setName("Eva").setOrder(2), new TestData().setName("Jane").setOrder(3), new TestData().setName("Jack").setOrder(4) }; } }
测试类:
1 public class TestData { 2 3 private String name; 4 private int order; 5 6 public String getName() { 7 return name; 8 } 9 10 public TestData setName(String name) { 11 this.name = name; 12 return this; 13 } 14 15 public int getOrder() { 16 return order; 17 } 18 19 public TestData setOrder(int order) { 20 this.order = order; 21 return this; 22 } 23 24 @Test 25 public void test(){ 26 System.out.println("order="+order); 27 System.out.println("Name="+name); 28 } 29 }
拦截器(关键):
public class MethodInterceptor implements IMethodInterceptor { @Override public List<IMethodInstance> intercept(List<IMethodInstance> list, ITestContext iTestContext) { Map<String,IMethodInstance> orders = new TreeMap<>(); // 有序map for (IMethodInstance instance : list) { TestData testData = (TestData) instance.getInstance(); orders.put(String.valueOf(testData.getOrder()), instance); } List<IMethodInstance> orderList = new ArrayList<>(list.size()); for (String order : orders.keySet()) { // 重新排序 IMethodInstance test = orders.get(order); orderList.add(test); } return orderList; // TestNG会按这个返回的List内实例的顺序来执行 } }
参考:
一开始在墙内怎么查都查不到可以排序的方法,直到FQgoogle……
https://stackoverflow.com/questions/10127280/make-testng-factory-test-cases-run-in-same-order-as-provided
https://www.ibm.com/developerworks/cn/opensource/os-cn-testinglistener/index.html