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

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

第一种:java

 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)。浏览器

第二种:session

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截图,截取的图片是浏览器中的网页。eclipse

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

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

 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>标签连同图片地址的源码输出到报表中。spa

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

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

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

    /**
     * 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中新建与其对应的同名包同名类,那么在项目运行过程当中,源码中的这个类就会被你新建的这个类覆盖啦。

相关文章
相关标签/搜索