我的测试类的设计方式是,当前的测试用例依赖于之前的测试用例。我必须为它实现重试机制。我使用-AnnotationTransformer和RetryAnalyzer进行了尝试。我面临的问题是,一旦测试用例失败,它将立即重新执行。@AfterClass方法和依赖的方法没有执行,因为测试用例的重试永远不会通过。例如,假设测试类是:
public class Gate{
@test
public void testCase1()
{
Login;
create new user;
logout;
}
@test
public void testCase2(dependsOnMethods = { "testCase1" }, enabled = true)
{
login with new user;
verify login;
}
}
如果我的测试用例未能验证登录步骤。我希望它首先执行@AfterClass方法,以便整个数据被丢弃,一切从头开始。
请建议我如何处理这种情况。
您应该使用TestListeners来满足这样的需求。这是一个例子-
import org.testng.ITestContext ;
import org.testng.ITestListener ;
import org.testng.ITestResult ;
public class ListenerTest implements ITestListener
{
@Override
public void onTestFailure(ITestResult result) {
//flush the data here
}
}
然后将此侦听器添加到您的testng xml文件中-
<listener class-name="//classpath to ListenerTest class" />
编辑-
这可能不是你想要的。首先,如果你想执行你的flush方法,你应该使用@AfterMethod
而不是@AfterClass
。后者将在你在一个类中的所有测试方法都被执行后执行,包括任何依赖的方法。假设你有@BeforeClass
,@BeforeMethod
,@AfterMethod
,@AfterClass
,那么执行的顺序TestNG将跟随Retry是(假设你的测试用例失败并且重试次数为1)-
1)@BeforeClass
2)@BeforeMethod
3)@测试(testCase1)
4)重试方法(在您的RetryAnalyzer实现中)
5)@后方法
6)@BeforeMethod
7)@测试(testCase1)
9)@后方法
10)像上面提到的任何测试侦听器
11)@BeforeMethod
12)@Test(您的下一个方法,即依赖的testCase2)
13)@后方法
14)@AfterClass(最终执行)
…等等。
因此,很明显,在您的测试(testCase1)第一次失败后,TestNG不会直接执行@AfterClass
方法,除非并且直到您的测试方法是类中存在的唯一方法。(事实并非如此,因为您在同一个类中有testCase2)。现在,您有两个选项可以放置您的flush()方法-
1)在RetryAnalyzer实现中的重试方法中
2)在您的@Aftermethod
中,但您需要检查已执行方法的结果状态,因为您可能只想在测试用例失败时执行它,类似于这样-
@AfterMethod(alwaysRun = true)
public void myAfterMethod(ITestResult testResult)
{
if(testResult.getStatus() == ITestResult.FAILURE)
{
failed_count++;
//flush();
}
}
但是依赖测试用例的执行呢?
依赖于失败的测试用例的测试用例将被TestNG跳过。额外的一点是,如果您希望任何测试方法无论如何都能被执行,即使它所依赖的测试方法失败了,请使用alwaysRun=true
。例如-
@Test(dependsOnMethods = { "test1" }, enabled = true, alwaysRun = true)
public void test2()
{
//this will be executed even if test1 fails
}