TestNG针对特定的API响应结果进行重试

Posted talentzemin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TestNG针对特定的API响应结果进行重试相关的知识,希望对你有一定的参考价值。

问题

有一个模块,提供两种方式导入数据,导入的过程是异步的。API处有校验,当有数据正在处理的时候,不能再导入,比如等待前一个导入结束。
我们针对这两种方式进行测试,当两个Test跑起来的时候,后面的case则无法通过test,因为前面的case创建了导入,导入状态还是In Process。

dependsOnMethods

所以,我们的要求就是,这两个case必须一个完成了才能进行下一个。很容易想到测试方法的依赖

@Test
public void test1() 
    


@Test(dependsOnMethods =  "test1")
public void test2() 
    

但是刚才也说了,数据是异步处理,test1执行完只能说明请求发送并得到响应,数据不一定处理完成。
所以,此方案不行。

Retry

那就后面执行的Test如果获取到API的500响应,如果是特定Message就重试呗。
重试我会写,但有没有很优雅的方式
有,TestNG提供IRetryAnalyzer接口,可以在用例执行失败后重新执行。

看看它的默认实现

public class DisabledRetryAnalyzer implements IRetryAnalyzer 
  @Override
  public boolean retry(ITestResult result) 
    return false;
  

默认就是不重试

如何使用

创建实现IRetryAnalyzer接口的类,并重写retry方法。

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class MyRetryAnalyzer implements IRetryAnalyzer 

    private int count = 0;
    private int maxCount = 3;

    @Override
    public boolean retry(ITestResult result) 
        if (count < maxCount) 
            count++;
            return true;
        
        return false;
    


在需要使用RetryAnalyzer的测试类或测试方法中,使用@Test注解并设置retryAnalyzer为MyRetryAnalyzer类即可。

import org.testng.annotations.Test;

public class MyTest 

    @Test(retryAnalyzer = MyRetryAnalyzer.class)
    public void testMethod() 
        // 测试方法逻辑
    



很好,很优雅。

现在的问题是,我我不能Case不过就重试3次,我只想要特定失败的情况下---前面提到的场景,才触发重试。
那只能从retry(ITestResult result) 这个参数下手了

@Test(retryAnalyzer = MyRetryAnalyzer.class)
public void testMethod() 
      var res = callAPI();
      if (resp.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR) 
            Reporter.getCurrentTestResult().setAttribute("api_error_response", res.getResponseAsString());
      


在MyRetryAnalyzer的实现中可以通过result.getAttribute拿到设置的值

public class MyRetryAnalyzer implements IRetryAnalyzer 

    private int count = 0;
    private int maxCount = 3;

    @Override
    public boolean retry(ITestResult result) 
        if (result.getAttribute("api_error_response").toString().contains("ERROR_MESSAGE")  && count < maxCount) 
            count++;
            return true;
        
        return false;
    


当然再优化下,增加重试的间隔,很直接,Sleep

public class MyRetryAnalyzer implements IRetryAnalyzer 

    private int count = 0;
    private int maxCount = 3;

    @Override
    public boolean retry(ITestResult result) 
        if (result.getAttribute("api_error_response").toString().contains("ERROR_MESSAGE")  && count < maxCount) 
            count++;
            try 
                Thread.sleep(3*1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            return true;
        
        return false;
    


结果

以上是关于TestNG针对特定的API响应结果进行重试的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud升级之路2020.0.x版-34.验证重试配置正确性

RestAssured 中的无效 JSON Schema 异常,同时针对来自 swagger 的模式进行验证

Appium失败截图及重试机制封装

URLSession dataTaskPublisher 在特定错误延迟后重试

返回空的特定搜索结果(Spotify API)

RocketMQ的消息重试