![](/img/trans.png)
[英]How to force TestNG create new instance of test class for each method if run mode is parallel=“methods”
[英]Making each test method run in its own instance of a test class with TestNG?
所以我认为下面的代码会在 TestNG 中运行良好,尽管它没有:
public class Tests {
int i = 0;
@Test
public void testA() {
Assert.assertEquals(0, i);
++i;
}
@Test
public void testB() {
Assert.assertEquals(0, i);
++i;
}
}
有没有办法让 TestNG 为每种测试方法启动一个新的测试 class ?
常见的解决方案是使用@BeforeMethod 方法设置测试 state,
@BeforeMethod
public void setup() {
i = 0;
}
到目前为止,我发现这个问题最常见的解决方案是使用 ThreadLocal 并处理这样一个事实,即每个测试 Class 只有一个实例。 这涉及有关如何处理并行/线程测试的所有问题。 这有效,但有点难看。
private ThreadLocal<Integer> i = new ThreadLocal<>();
@BeforeMethod
public void setup() {
i.set(0);
}
@Test
public void testA() {
Integer i1 = i.get();
Assert.assertEquals(0, i.get().intValue());
i.set(i1 + 1);
}
@Test
public void testB() {
Integer i1 = i.get();
Assert.assertEquals(0, i.get().intValue());
i.set(i1 + 1);
}
现在回到问题的根源,每种方法的新实例。 我已经研究了几个星期类似的主题,我发现这是我个人在 TestNG 遇到的第一个问题。 它真的让我发疯了。
如果我忽略了你的测试有很多复杂性这一事实,你可能会拼凑出一个解决方法来满足你列出的要求。
TestNG @Factory Factory 允许您创建测试类的新实例。
@Factory
public Object[] factory(){
return new Object[]{new Tests(), new Tests()};
}
我现在创建了两个Tests
实例,由 testNG 运行
那么问题是您的测试仍然失败,因为它会尝试在您的测试类上运行所有测试方法。 为了解决这个问题,您可以实现一个 IMethodInterceptor,并将一个解决方案组合在一起以强制每个 Tests 实例只运行一个方法。 维护一个方法列表,go 一次一个地通过它们。
这是我一起破解的一个粗略的例子。
public class TestFactory implements IMethodInterceptor {
private List<String> methodsToRun = new ArrayList<>();
private List<Object> testInstances = new ArrayList<>();
@Factory
public Object[] factory(){
return new Object[]{new Tests(), new Tests()};
}
@Override
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
ArrayList<IMethodInstance> tempList = new ArrayList<>();
for(IMethodInstance i: methods){
if(testInstances.contains(i.getInstance())){
continue;
}
String mName = i.getMethod().getConstructorOrMethod().getName();
if(!methodsToRun.contains(mName)){
tempList.add(i);
methodsToRun.add(mName);
testInstances.add(i.getInstance());
}
}
return tempList;
}
}
然后将您的侦听器添加到您的Tests
顶部 class
@Listeners(TestFactory.class)
您可以通过在工厂中动态创建测试的新实例来改进这一点。 还将侦听器分解为它自己的文件和许多其他改进,但你明白了要点。
也许像上面这样的疯狂解决方案对您或其他人有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.