所以我认为以下代码在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为每个测试方法启动一个新的Tests类?
答案 0 :(得分:4)
常见的解决方案是使用@BeforeMethod方法设置测试状态,
@BeforeMethod
public void setup() {
i = 0;
}
答案 1 :(得分:0)
到目前为止,我发现这个问题最常见的解决方案是使用ThreadLocal,并且只处理每个Test 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实例只运行一个方法。维护一个方法列表,并一次一个地浏览它们。
这是我一起攻击的一个野蛮例子。
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
班级
@Listeners(TestFactory.class)
您可以通过在工厂中动态创建测试的新实例来改进这一点。同时打破了聆听者自己的文件和许多其他改进,但你得到了要点。
也许像上面这样疯狂的解决方案对你或其他人有用。