zoukankan      html  css  js  c++  java
  • TestNG监听器实现用例运行失败自动截图、重运行功能

    注: 以下内容引自 http://blog.csdn.net/sunnyyou2011/article/details/45894089 (此非原出处,亦为转载,但博主未注明原出处)

    使用Testng框架搭建自动测试框架,经常会需要增加失败自动截图,以及失败重跑功能,下面介绍一下不修改Testng的源码,通过监听器的方式来实现自动截图、重跑、以及自定义生成的Html结果文件功能。

    自动截图功能
    1、新建一个Java类继承TestListenerAdapter
    2、重写onTestFailure、onTestSkipped等方法,在这些方法中加入截图操作
    3、在testng.xml文件中配置自己编写的监听器类

    
    

    <listeners>

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



    
    

    public class TestngListener extends TestListenerAdapter private static Logger logger = Logger.getLogger(TestngListener.class); public static final String CONFIG = "config.properties"@Override public void onTestFailure(ITestResult tr) super.onTestFailure(tr); logger.info(tr.getName() + " Failure"); takeScreenShot(tr); @Override public void onTestSkipped(ITestResult tr) super.onTestSkipped(tr); logger.info(tr.getName() + " Skipped"); takeScreenShot(tr); @Override public void onTestSuccess(ITestResult tr) super.onTestSuccess(tr); logger.info(tr.getName() + " Success"); @Override public void onTestStart(ITestResult tr) super.onTestStart(tr); logger.info(tr.getName() + " Start"); @Override public void onFinish(ITestContext testContext) super.onFinish(testContext); /** * 自动截图,保存图片到本地以及html结果文件中 * @param tr */ private void takeScreenShot(ITestResult tr) SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); String mDateTime = formatter.format(new Date()); String fileName = mDateTime + "_" + tr.getName(); String filePath = OrangeiOS.driver.getScreenshotAs(fileName); Reporter.setCurrentTestResult(tr); Reporter.log(filePath);

    //这里实现把图片链接直接输出到结果文件中,通过邮件发送结果则可以直接显示图片 Reporter.log("<img src="../" + filePath + ""/>"); }



    失败自动重跑功能
    1、新建Java类实现IRetryAnalyzer接口

    
    

    public class TestngRetry implements IRetryAnalyzer private static Logger logger = Logger.getLogger(TestngRetry.class); private int retryCount = 1private static int maxRetryCountprivate static ConfigReader configstatic {

    //外围文件配置最大运行次数 config = new ConfigReader(TestngListener.CONFIG); maxRetryCount = config.getMaxRunCount(); logger.info("maxRunCount=" + (maxRetryCount)); @Override public boolean retry(ITestResult result) if (retryCount <= maxRetryCount) String message = "running retry for '" + result.getName() + "' on class " +

    this.getClass().getName() + " Retrying " + retryCount + " times"logger.info(message); Reporter.setCurrentTestResult(result); Reporter.log("RunCount=" + (retryCount + 1)); retryCount++; return truereturn false}

    2、新建Java类实现IAnnotationTransformer接口

    
    

    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、在build.xml或者testng.xml文件中添加RetryListener监听器

    上面三步就可以实现失败自动重跑了,是不是比较方便,不过添加了重跑功能后会发现测试结果的邮件中用例的个数增加了,比如我只有一个用例,失败重跑了2次,一共运行3次,测试结果中显示的用例个数会是3个,那接下来就需要解决这个问题了。

    首先解决TestNg生成的index.html文件中个数不对的问题,这个问题只需要在Testng监听器的onFinish方法中,等所有用例运行完之后,检查用例,按照class+method+dataprodiver的名称生成hashcode获取唯一id,如果fail的用例中存在重复的则在 fail的用例中剔除掉,具体代码如下:

    
    

    @Override public void onFinish(ITestContext testContext) super.onFinish(testContext); // List of test results which we will delete later ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>(); // collect all id's from passed test Set<Integer> passedTestIds = new HashSet<Integer>(); for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) logger.info("PassedTests = " + passedTest.getName()); passedTestIds.add(getId(passedTest)); Set<Integer> failedTestIds = new HashSet<Integer>(); for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) logger.info("failedTest = " + failedTest.getName()); // id = class + method + dataprovider int failedTestId = getId(failedTest); // if we saw this test as a failed test before we mark as to be deleted // or delete this failed test if there is at least one passed version if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) testsToBeRemoved.add(failedTest); } else failedTestIds.add(failedTestId); // finally delete all tests that are marked for (Iterator<ITestResult> iterator =

    testContext.getFailedTests().getAllResults().iterator(); iterator.hasNext();) ITestResult testResult = iterator.next();if (testsToBeRemoved.contains(testResult)) logger.info("Remove repeat Fail Test: " + testResult.getName()); iterator.remove(); private int getId(ITestResult result) int id = result.getTestClass().getName().hashCode(); id = id + result.getMethod().getMethodName().hashCode(); id = id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0); return id}



    当前失败重跑也存在一些小问题:
    1、setup中出现的错误直接是skip的,不会重跑
    2、如果存在dataprodiver,则第二组数据以后的用例是不会重跑的
    3、testng自带生成的emailable-report.html文件中用例的个数也不对了,这个问题可以自行修改EmailableReporter.java文件


    如何修改自定义emailable-report.html

    emailable-report.html是Testng运行完成后自动生成的,经常运行结束后我们会把这个文件作为邮件正文发送给收件人,如果我们要修改这个文件内容怎么办呢?

    1、首先emailable-report.html文件的生成TestNG是实现了IReporter接口,那我们可以直接从源代码中取出这个文件源代码
    https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/reporters/EmailableReporter.java
    2、针对源代码进行自己修改
    3、把修改后的源代码加入自己的工程
    4、在build.xml文件中新增自定义的监听器,运行时就会调用自定义的监听器生成想要的html文件了

    
    

    <testng outputDir="test-output" classpathref="http://qa.blog.163.com/blog/runpath" haltonfailure="false" listeners="com.****.CustomerEmailableReport" <xmlfileset dir="." includes="${testngxml}.xml" /> </testng>

  • 相关阅读:
    DGA域名可以是色情网站域名
    使用cloudflare加速你的网站隐藏你的网站IP
    167. Two Sum II
    leetcode 563. Binary Tree Tilt
    python 多线程
    leetcode 404. Sum of Left Leaves
    leetcode 100. Same Tree
    leetcode 383. Ransom Note
    leetcode 122. Best Time to Buy and Sell Stock II
    天津Uber优步司机奖励政策(12月28日到12月29日)
  • 原文地址:https://www.cnblogs.com/cheese320/p/8478609.html
Copyright © 2011-2022 走看看