selenium - Testng失敗后截圖和重跑

前言

  • 在運行自動化測試腳本時,經(jīng)常會需要增加失敗時自動截圖功能,以及失敗重跑功能,下面我們通過Testng監(jiān)聽器的方式來實現(xiàn)自動截圖和重跑功能。

一、創(chuàng)建一個ResultTest 接口

// ResultTest 接口主要用于實例的轉(zhuǎn)換
public interface ResultTest {

    DriverBase DriverBase();
}
// 將所有 Test Case 繼承 ResultTest 接口,并 reutrn driverBase 返回
public class CanvasExpressionTest implements ResultTest {
 private DriverBase driverBase = new DriverBase("HomeData.BROWSER") ;

 @Override
    public DriverBase DriverBase() {
        return driverBase;
    }
}

二、創(chuàng)建一個截圖工具類:ScreenshotUtils

/** 截圖工具類 */
public class ScreenshotUtils {

    private DriverBase driverBase;

    public ScreenshotUtils(DriverBase driverBase) {
        this.driverBase = driverBase;
    }
    
    
    public void getScreenshot(String methodName) {
        // 截圖主體功能
        File screen = ((TakesScreenshot) driverBase.getDriver()).getScreenshotAs(OutputType.FILE);
        // 拼接路徑和圖片名稱
        String xpath = "./image/error/" + methodName + "_" + getCurrentTime() + ".png";
        File screenFile = new File(xpath);
        try {
            FileUtils.copyFile(screen,screenFile);
            LogUtils.info(" 截圖保存路徑 ",xpath);
        } catch (Exception e) {
            LogUtils.error(" 截圖保存失敗 ",xpath);
            e.printStackTrace();
        }
    }

    /** 獲取當(dāng)前時間 */
    private String getCurrentTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        return sdf.format(date);
    }
}

三、創(chuàng)建一個Java 類并繼承 TestListenerAdapter 類

  • 在 TestNG 中 TestListenerAdapter為監(jiān)聽器類,主要使用如下方法:
    • onStart(ITestContext testContext):在測試類實例化之后,調(diào)用任何配置方法之前調(diào)用
    • onFinish(ITestContext testContext):在所有測試運行并調(diào)用其所有配置方法后調(diào)用
    • onTestStart(ITestResult tr):每次在測試被調(diào)用之前調(diào)用
    • onTestFailure(ITestResult tr):每次測試失敗時調(diào)用
    • onTestSkipped(ITestResult tr):每次跳過測試時調(diào)用
    • onTestSuccess(ITestResult tr):每次測試成功時調(diào)用
想實現(xiàn) case 運行失敗時自動截圖,只需要新建一個類 TestNGListener 繼承 TestListenerAdapter ,然后重寫 onTestFinish、onTestSkipped 等方法,并在這些方法加入截圖操作即可
public class TestNGListener extends TestListenerAdapter {

  /** 重寫 onTestFinish 方法 */
  @Override
  public void onTestFailure(ITestResult tr) {
    LogUtils.error("Test Failure", null);
    // 獲取示例并轉(zhuǎn)換為 ResultTest 
    ResultTest result = (ResultTest) tr.getInstance();
    // 調(diào)用截圖方法,并傳入方法名稱作為圖片名稱
    String methodName = tr.getMethod().getMethodName();
    new ScreenshotUtils(result.DriverBase()).getScreenshot(methodName);
  }
}

在 TestNG.xml 文件中配置自己編寫的監(jiān)聽類

    <listeners>
        <listener class-name="testng.TestNGListener"/>
    </listeners>

四、失敗時自動重跑

1. 創(chuàng)建一個 TestngRetry 類并繼承 IRetryAnalyzer 接口實現(xiàn) retry 方法,并實現(xiàn)重跑邏輯
  - 返回 true : 代表重跑
  - 返回 false :關(guān)閉重跑
public class TestngRetry  implements IRetryAnalyzer {

  private static  int retryCount         = 1;         // 定義重跑次數(shù)
  private static final int maxRetryCount = 3;         // 定義最大重跑次數(shù)

  @Override
  public boolean retry(ITestResult result) {
    if (retryCount < maxRetryCount){
      LogUtils.error("retryCount" , retryCount);
      retryCount ++;
      return true;
    }
    return false;
  }
}
2. 添加用例重跑監(jiān)聽器 RetryListener 繼承 IAnnotationTransformer 接口實現(xiàn)transform方法,實現(xiàn)用例失敗時重跑功能
public class RetryListener implements IAnnotationTransformer {

  @Override
  public void transform(ITestAnnotation annotation,
                        Class testClass,
                        Constructor testConstructor,
                        Method testMethod) {

    IRetryAnalyzer retry = annotation.getRetryAnalyzer();
    if (retry == null){
       annotation.setRetryAnalyzer(TestngRetry.class);
    }
  }
}
3. 在TestNG.xml 文件中配置編寫的監(jiān)聽器
 <listeners>
        <listener class-name="testng.TestNGListener"/>
        <listener class-name="testng.RetryListener"/>
 </listeners>
4. 進(jìn)一步改進(jìn)重跑功能

以上三個步驟可以搞定 case 失敗時重跑的功能,但是會在結(jié)果中會發(fā)現(xiàn)失敗的 case 會生成多個,顯然這樣是不好的

// 此時就需要在之前寫的 TestNGListener監(jiān)聽器類中重寫onFinish 方法
@Override
  public void onFinish(ITestContext testContext) {
    removeFailed(testContext);
  }

  private void removeFailed(ITestContext context) {
    Iterator<ITestResult> iterator = context.getFailedTests().getAllResults().iterator();

    while (iterator.hasNext()) {
      ITestResult failedTest = iterator.next();
      ITestNGMethod method = failedTest.getMethod();
      if (context.getFailedTests().getResults(method).size() > 1) {
         iterator.remove();
      } else {
          if (context.getPassedTests().getResults(method).size() > 0 ){
            iterator.remove();
          }
      }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 感謝原作者的奉獻(xiàn),原作者博客地址:http://blog.csdn.net/zhu_ai_xin_520/arti...
    狼孩閱讀 14,299評論 1 35
  • 背景 UI自動化腳本執(zhí)行過程中存在非常多的不穩(wěn)定性,例如網(wǎng)絡(luò)的不穩(wěn)定,瀏覽器無響應(yīng)等等,這些失敗往往并不是產(chǎn)品中的...
    博客已遷移I米陽閱讀 2,835評論 4 12
  • TestNG默認(rèn)情況下,會生產(chǎn)兩種類型的測試報告HTML的和XML的。 測試報告位于 "test-output" ...
    我為峰2014閱讀 8,020評論 0 5
  • 刀在我的血液里沸騰 驕傲的鐵質(zhì) 摩擦著我的胸膛 一把刀是在夢中銹掉還是在現(xiàn)實中磨礪? 在來不及思考的間隙 已被刀鞘...
    江南奕帆閱讀 192評論 0 1
  • 文 | 叫我阿斌啦(微信公眾號:快樂傳遞者) 愛一個人是什么感覺,如果當(dāng)你愛上對方時,應(yīng)該會有這九種情感...
    叫我阿斌啦閱讀 680評論 0 3

友情鏈接更多精彩內(nèi)容