提问者:小点点

TestNG使用RetryAnalyzer重试中的依赖测试用例


我的测试类的设计方式是,当前的测试用例依赖于之前的测试用例。我必须为它实现重试机制。我使用-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方法,以便整个数据被丢弃,一切从头开始。

请建议我如何处理这种情况。


共1个答案

匿名用户

您应该使用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
    }