TestNG在生成的报表中添加自动截图


首先说一下截图的方式把,我用过两种。

第一种:

 1 public static void screenShotAsFile(int x, int y, int width, int height, String fileName) {
 2         try {
 3             Robot robot = new Robot();
 4             BufferedImage bfImage = robot.createScreenCapture(new Rectangle(x, y, width, height));
 5             File path = new File("D:\\eclipseFile\\baiduFile");
 6             File file = new File(path, fileName+ "." + "jpg");
 7             ImageIO.write(bfImage, "jpg", file);
 8         } catch (AWTException e) {
 9             e.printStackTrace();    
10         } catch (IOException e) {
11             e.printStackTrace();
12         }
13     }

这一种,可以自定义截图的区域。我在使用中需要截取不含电脑桌面下方菜单栏的图片,也就是浏览器全屏显示界面的区域,使用的值是(0, 0, 1360, 716)。

第二种:

public static void getScreenshot(WebDriver driver, String photoName) {
        try {
            // 获得屏幕截图并以文件的形式返回
            File srcFile = ((TakesScreenshot) driver)
                    .getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(srcFile, new File("D:\\eclipseFile\\baiduFile\\"
                    + potoName + "_screenshot.jpg"));
        } catch (Exception e) {
            e.printStackTrace();
        }
 }

 

这一种是利用WebDriver截图,截取的图片是浏览器中的网页。

这两种方式都很简单实用,在自动化测试中,我更倾向于第二种方式,没有为什么,觉得用的更舒服一些。但有一点我觉得很讨厌,使用这种方式封装的方法须给它传进一个WebDriver参数。这个真的很烦啊,比如我在自动化测试中,想在测试到异常后统一调用这个方法进行截图,由于测试用到的其它方法都是封装好了,而且一个用例里面我必须保持一个driver,新的用例必须使用新的driver(每一次测试需重新建立一个新的session),由于每次用例的driver不是共享的,所以在最后很难统一来处理(比如将其放在@aftertest标签下调用),我不可能为了调用它去重新new一个driver把,所以我目前的解决办法就是将其放在其它传有driver对象的方法里调用,即使如此,我依旧觉得麻烦。

通过上面的截图方式,会将图片保存到你指定的存储地址中,如果我们想在测试结果的报表中显示图片,那么只需在日志中输出包含图片地址的<img>标签就好了,如下:

 public static void sendReport(String typeSend, String txt) {
       Reporter.setEscapeHtml(false);
       String sreenShotLink = "<a href=\"file:///D:\\eclipseFile\\baiduFile\\"+ txt + "_screenshot.png\" target=\"_blank\">截图名称:" + txt + "</a>";
       String sreenShotImg = "<p>截图:<img id=\"img\" src=\"file:///D:\\eclipseFile\\baiduFile\\" + txt + "_screenshot.png\" alt=\"Smiley face\" width=\"200\" height=\"200\"></p>";
       String reportStr = txt;
       switch (typeSend) {
       case "link":
           Reporter.log(sreenShotLink);
           break;
       case "img":
           Reporter.log(sreenShotImg);
           break;
       case "txt":
           Reporter.log(reportStr);
           break;
       default:
           break;
        }
    }

但是,现在存在一个问题,当我们将包含图片地址的<img>标签输出到TestNG日志中时,出人意料的是图片并没有显示,我去,它竟然将整个<img>标签连同图片地址的源码输出到报表中。

为什么会这样呢?答案其实很明显,整个<ing>标签的源码在输出到ReportNG报表的html文档的过程中被TestNG给转义了(你可以用UE查看下报表文档的html源码),这就很腻害呢!

当时在百度的过程中,看到一些“老油条”,是用自己写的方法,将地址传到报表文档中,但这些“老油条”都写的很简略,虽然贴出了代码,但传递的具体机制,却说的很模糊,自己试了试,遗憾并没有成功。我当时就有个想法,我已经知道,它既然是被TestNG转义了,那我只需找到源码中转义的地方,稍稍的修改下源码,<img>标签不就可以正常输出了吗?

基于上面的想法,我马上找到了案发的第一现场:

    /**
     * Converts a char into a String that can be inserted into an XML document,
     * replacing special characters with XML entities as required.
     * @param character The character to convert.
     * @return An XML entity representing the character (or a String containing
     * just the character if it does not need to be escaped).
     */
    private String escapeChar(char character)
    {
        switch (character)
        {
            case '<': return "<";
            case '>': return ">";
            case '"': return """;
            case '\'': return "'";
            case '&': return "&";
            default: return String.valueOf(character);
        }
    }

 

它的地址位于reportng JAR包下org.uncommons.reportng包下的ReportNGUtils.java

这样解决办法就一目了然了啊,将被转义的地方注释掉就好了嘛。

至于如何修改JAR包中的源码,直接找到这个java类的源码,在eclipse中新建与其对应的同名包同名类,那么在项目运行过程中,源码中的这个类就会被你新建的这个类覆盖啦。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM