使用RetryAnalyzer在TestNG重试中的相关测试用例

时间:2018-08-03 03:24:52

标签: testng

我的测试类的设计方式使得当前测试用例依赖于先前的测试用例。我必须为此实现一个重试机制。我尝试使用-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 个答案:

答案 0 :(得分:0)

您应使用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" />

编辑-

这可能不是您想要的。首先,如果要执行冲洗方法,则应使用@AfterMethod而不是@AfterClass。后者将在类中的所有测试方法(包括任何相关方法)执行后 执行。假设您有@BeforeClass@BeforeMethod@AfterMethod@AfterClass,则TestNG的执行顺序将与Retry一起执行(假设您的测试用例失败并且重试计数为1)-

1)@BeforeClass

2)@BeforeMethod

3)@Test(testCase1)

4)重试方法(在您的RetryAnalyzer实现中)

5)@AfterMethod

6)@BeforeMethod

7)@Test(testCase1)

9)@AfterMethod

10)任何上述测试监听器

11)@BeforeMethod

12)@Test(您的下一个方法,即从属的一个testCase2)

13)@AfterMethod

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
    }