工厂注解的执行顺序与我们配置实例的顺序不同
Factory annotation does not execute in the same order we configure the instances
我尝试使用@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;
}
}
主要class:
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 时,结果与我们从工厂传递的顺序不同。我们如何确保输出与我们传递的值相同?
如果没有定义其他顺序选项,测试方法按其
排序
<test-method-instance> name + <test-class-instance>.toString()
由于test-class.toString()
总是有一些随机部分,如MainImpClass@28a0fd6c
,默认的执行顺序是偶然的。
简化执行顺序的最简单方法是覆盖 test-class toString()
方法,例如:
@Override
public String toString() {
return "MainImpClass" + a;
}
但这并没有回答您关于如何按照工厂提供的订单进行测试的问题。
如何保持Factory-defined订单
注意:这不是通用解决方案,仅适用于这个简单的上下文。
测试Class
添加了在 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
工厂Class
添加了 groupByOrder
方法,该方法根据数组中出现的 class 次设置顺序。
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>
...
我尝试使用@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;
}
}
主要class:
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 时,结果与我们从工厂传递的顺序不同。我们如何确保输出与我们传递的值相同?
如果没有定义其他顺序选项,测试方法按其
排序<test-method-instance> name + <test-class-instance>.toString()
由于test-class.toString()
总是有一些随机部分,如MainImpClass@28a0fd6c
,默认的执行顺序是偶然的。
简化执行顺序的最简单方法是覆盖 test-class toString()
方法,例如:
@Override
public String toString() {
return "MainImpClass" + a;
}
但这并没有回答您关于如何按照工厂提供的订单进行测试的问题。
如何保持Factory-defined订单
注意:这不是通用解决方案,仅适用于这个简单的上下文。
测试Class
添加了在 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
工厂Class
添加了 groupByOrder
方法,该方法根据数组中出现的 class 次设置顺序。
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>
...