我尝试使用@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
如何改进
一些更通用的解决方案可以使用IMethodInterceptor
TestNG侦听器来实现。
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>
...