有赞测试 如何利用 TestNG 监听器优化测试报告

有赞测试团队 · 2018年11月11日 · 1549 次阅读

作者:
Winta | 27 Nov 2015 | (4372 words)

如何利用 TestNG 监听器优化测试报告

MacDown logo

今年四月底我花了一天时间简单搭建了 php 接口测试工程,maven + TestNG + jenkins,从 0 开始到现在 510 个用例(持续增长中),逐渐开始提高了测试回归效率并发现一些线上 bug,这期间遇到过不少问题,这次先分享下如何利用 TestNG 监听器优化测试报告

一、给工程添加失败重试机制

接口用例量上来以后,我们遇到的第一个问题就是 http 方式调用 php 接口会有部分接口偶尔不稳定或者超时的情况,但第二次运行又正常,每次接口失败都需要花费时间排查,但实际没有问题,为了排除不稳定带来的干扰,节约排查维护时间,首先需要做的是给工程添加失败自动重试机制。
目前我的做法是实现了 TestNG 自带的 IRetryAnalyzer 接口,定义了一个 MAX_RETRY_COUNT,即最大重试次数,实现的 retry 方法非常简单,如下:

public boolean retry(ITestResult result) {  
    if (retryCount < MAX_RETRY_COUNT) {
        retryCount++;
        return true;
    }
    return false;
}

如果团队有人想要使用失败重试的功能也很简单,只需要在 Annotation 里面加上 retryAnalyzer 属性即可,如下:

@Test(retryAnalyzer = TestRetry.class)
public void summaryTest(){  
  String url = urlList.get(0);
  JSONObject map = ResponseJsonBase.manageJson(url, "");
  String total = map.getString("total");
  assert "7.59".equals(total) : url;
}

这种方式带来的好处是有比较大的自由度,可以自由选择某个用例是否需要失败重试的功能,因为部分接口重试第二次是不允许的,比如有频率限制的接口等。 但是加了失败重试机制以后,我们会发现接口测试报告有问题:一是被失败重试的用例被重复输出了,二是即使失败重试后通过的情况,依然会有邮件 “骚扰”,还是需要花费很多时间看接口问题。
有问题的接口测试报告如下:

MacDown logo

二、通过定义一个监听器优化测试报告

根据遇到的问题,首先我们需要优化一下测试报告,从而避免给大家带来太多干扰。 我的做法是定义了一个 TestNG 的监听器来处理失败重试的用例。具体实现是通过继承 TestListenerAdapter 类,覆盖 onTestFailure、 onStart、 onFinish 方法,贴一下主要的代码段:

@Override
public void onTestFailure(ITestResult tr) {  
  if (tr.getMethod().getRetryAnalyzer() == null) {
  log(tr.getMethod() + "--Test method failed\n");
  }

  if (tr.getMethod().getRetryAnalyzer() != null) {
  TestRetry testRetry = (TestRetry)       tr.getMethod().getRetryAnalyzer();
  if (testRetry.getRetryCount() < testRetry.getMaxRetryCount()) {
    tr.setStatus(ITestResult.SKIP);
    Reporter.setCurrentTestResult(null);
    isRemoveSkipNeeded = true;
    skippedCases.addResult(tr, tr.getMethod());
  } 
  else {
    failedCases.addResult(tr, tr.getMethod());
    isRetryNeeded = true;
  }
 }
}

其实上面代码里面就是统一对失败的用例做处理,每次失败都会去判断是否已经达到最大失败次数,如果没有,会将该用例状态设置为 skip,到这里为止,看我们的测试报告,大概长这样:

MacDown logo

可以看到,依然有很明显的问题,所以第二步要做的事情是:失败的用例列表去重,以及在 Skipped 的 Test Case 里面剔除真正 Failed 的 Test Case。 其实测试报告的主要数据获取是下面几个:

getFailedConfigurations()  
getSkippedConfigurations()  
getFailedTests()  
getSkippedTests()  

做对应优化就很简单了,贴下我这边 failed Cases 去重的代码段,可以举一反三写其他几个:

private void removeFailedTestsInTestNG(ITestContext test) {  
  IResultMap returnValue = test.getFailedTests();
  for (ITestResult resultToCheck : failedCases.getAllResults()) {
  int c = 0;
  for (ITestResult result : returnValue.getAllResults()) {
    if (result.getMethod().equals(resultToCheck.getMethod())) {
      c++;
      if (c > 1) {
        returnValue.removeResult(result.getMethod());
        test.getFailedConfigurations().removeResult(
        result.getMethod());
        }
      }
    }
  }
}

然后就是在每个 testSuit 运行结束的时候,统一处理:

@Override
public void onFinish(final ITestContext testContext) {  
  if(isRetryNeeded){
  removeIncorrectlySkippedTests(testContext,failedCases);
  removeFailedTestsInTestNG(testContext);
}
else{  
  if(isRemoveSkipNeeded)
    removeSkippedTestsInTestNG(testContext);
  else{
    skippedCases= testContext.getSkippedTests();
    failedCases= testContext.getFailedTests();
    }
  }
}

将该监听器配置到 testng.xml 内或者 pom.xml 内就可以生效了。
自此为止,看下我们的测试报告已经是我们想要的样子了:

MacDown logo

最后就是 CI 的配置,我用了扩展邮件插件,实现了一个相对直观的邮件模版,只对 Fail 和 Fixed 的情况进行提醒(见下图右),对于 skipped 的用例,虽然不再有邮件 “骚扰”,但依然可以在 jenkins 里面查看(见下图左):

MacDown logo

三、后续的优化空间

上周,我在工程里面加了日志模块,会记录 skip 的和返回时间超过 1 秒的用例,设想是运行一段时间后,对这部分用例进行统计,看是否接口本身存在优化空间。这部分工作后续计划优化为自动完成、自动出图表,要看时间是否充足了。

原文链接

欢迎关注我们的公众号
MacDown logo

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册