工厂注释的执行顺序与我们配置实例的顺序不同



我尝试使用@Factory在多个实例中运行同一个class。请注意,我是TestNG的初学者。

例如:

@Factory的实现:

public class MainFactoryClass{
@Factory
public Object[] mainFactory() {
Object[] data = new Object[3];
data[0] = new MainImpClass(9);
data[1] = new MainImpClass(10);
data[2] = new MainImpClass(11);
return data;
}
}

和主类:

public class MainImpClass {
int a;
public MainImpClass(int a) {
this.a = a;
}

@Test
public void getValue1() {   
System.out.println("Value from getValue1: " + a);
}
@Test
public void getValue2() {
System.out.println("Value from getValue2: " + a);
}
@Test
public void getValue3() {
System.out.println("Value from getValue3: " + a);
}
}

实际:

Value from getValue1: 9
Value from getValue2: 9
Value from getValue3: 9
Value from getValue1: 11
Value from getValue2: 11
Value from getValue3: 11
Value from getValue1: 10
Value from getValue2: 10
Value from getValue3: 10

testng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Factory Suite">
<test thread-count="5" name=" Factory Test" group-by- 
instances="true">
<classes>
<class name="com.trial.MainFactoryClass"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->

更新-实现IMethodInterceptor:

@Override
public List<IMethodInstance> intercept(List<IMethodInstance> list, 
ITestContext iTestContext) {
Map<Integer, IMethodInstance> orders = new TreeMap<>(); // 
Ordered MAP

for (IMethodInstance instance : list) {
MainImpClass testData = (MainImpClass) 
instance.getInstance();
orders.put(Integer.valueOf(testData.getA()), instance);

}

List<IMethodInstance> orderList = new 
ArrayList<IMethodInstance>(list.size());


for (Integer order : orders.keySet()) { // rearrange
IMethodInstance test = orders.get(order);
orderList.add(test);
}
return orderList; // TestNG will execute in the order  
return List
}

当我尝试将其作为TestNG运行时,结果与我们从Factory传递的顺序不同。我们如何确保输出与我们传入值的方式相同?。

如果没有定义其他订单选项,则测试由其订购的方法

<test-method-instance> name + <test-class-instance>.toString()

由于test-class.toString()总是有一些像MainImpClass@28a0fd6c一样的随机部分,因此默认执行顺序是偶然的。

简化执行顺序的最简单方法是重写测试类toString()方法,如:

@Override
public String toString() {
return "MainImpClass" + a;
}

但这并不能回答您关于如何在工厂提供的订单中订购测试的问题。

如何保持工厂定义的订单

注意:这不是一个通用的解决方案,只是针对这个简单的上下文。

测试类

添加了toString()中引用的私有order变量。

public class MainImpClass {
int a;
private int order = 0;
public MainImpClass(int a) {
this.a = a;
}
@Override
public String toString() {
return "MainImpClass" + order;
}
void setOrder(int order) {
this.order = order;
}
// ... rest of class

工厂级

添加了groupByOrder方法,该方法根据数组中的类出现情况设置顺序。

public class MainFactoryClass {
@Factory
public Object[] mainFactory() {
Object[] data = new Object[3];
data[0] = new MainImpClass(9);
data[1] = new MainImpClass(10);
data[2] = new MainImpClass(11);
return groupByOrder(data);
}
private static Object[] groupByOrder(Object[] data) {
for (int i = 0; i < data.length; i++) {
((MainImpClass) data[i]).setOrder(i);
}
return data;
}
}

输出

Value from getValue1: 9
Value from getValue1: 10
Value from getValue1: 11
Value from getValue2: 9
Value from getValue2: 10
Value from getValue2: 11
Value from getValue3: 9
Value from getValue3: 10
Value from getValue3: 11

testng.xml中应用group-by-instances="true"的输出

Value from getValue1: 9
Value from getValue2: 9
Value from getValue3: 9
Value from getValue1: 10
Value from getValue2: 10
Value from getValue3: 10
Value from getValue1: 11
Value from getValue2: 11
Value from getValue3: 11

如何改进

一些更通用的解决方案可以使用IMethodInterceptorTestNG侦听器来实现。

class TestsOrderInterceptor implements IMethodInterceptor {
@Override
List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
// sort by some rule
}
}

并应用监听器

@Listeners(TestsOrderInterceptor.class)
public class MainFactoryClass {

或在XML套件中

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="factory-tests">
<listeners>
<listener class-name="TestsOrderInterceptor"/>
</listeners>
...

最新更新