reportNG定制化之失败截图及日志
先从github上拉下 reportNg的源代码 reportng
拉下源码后我们使用IDEA进行导入
1、reportng.properties 增加部分类表项
这里我们直接在末尾添加
1 2 3 | log=Log Info screenshot=Screen Shot duration=Duration |
2、results.html.vm 修改结果的html,我们目前只修改fail的情况下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #if ($failedTests.size() > 0) <table class= "resultsTable" > < tr ><th colspan= "5" class= "header failed" >$messages.getString( "failedTests" )< /th >< /tr > #foreach ($testClass in $failedTests.keySet()) < tr > <td colspan= "1" class= "group" >$testClass.name< /td > <td colspan= "1" class= "group" >$messages.getString( "duration" )< /td > <td colspan= "1" class= "group" >$messages.getString( "log" )< /td > <td colspan= "1" class= "group" >$messages.getString( "screenshot" )< /td > < /tr > #set ($classResults = $failedTests.get($testClass)) #parse ("org/uncommons/reportng/templates/html/class-results.html.vm") #end < /table > #end |
3、我们在class-results.html.vm中最后加入一列,来显示图片,注意我们使用的是$utils.getImageString($line)
而不是$utils.escapeHTMLString($utils.removeImage($line))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <td class= "screenshot" > #set ($output = $utils.getTestOutput($testResult)) #if ($output.size() > 0) <div class= "screenshotimage" > #foreach( $line in $output ) #if ($meta.shouldEscapeOutput()) $utils.getImageString($line)<br /> #else $utils.getImageString($line)<br /> #end #end < /div > #end < /td > |
上面出现的两个方法getImageString,removeImage。 就是提取含有img标签的字符串和去除带有img标签的字符串。
可以在ReportNGUtils.java中看到,生成到报告中的内容如果用escapeHTMLString会被转义,这里插入的图片我们之后通过Reporter.log()方式写入,因此写入的标签我们不希望被转义。
public String escapeString(String s) { if (s == null) { return null; } StringBuilder buffer = new StringBuilder(); for(int i = 0; i < s.length(); i++) { buffer.append(escapeChar(s.charAt(i))); } return buffer.toString(); } /** * 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); } } public String escapeHTMLString(String s) { if (s == null) { return null; } StringBuilder buffer = new StringBuilder(); for(int i = 0; i < s.length(); i++) { char ch = s.charAt(i); switch (ch) { case ' ': // All spaces in a block of consecutive spaces are converted to // non-breaking space ( ) except for the last one. This allows // significant whitespace to be retained without prohibiting wrapping. char nextCh = i + 1 < s.length() ? s.charAt(i + 1) : 0; buffer.append(nextCh==' ' ? " " : " "); break; case '\n': buffer.append("<br/>\n"); break; default: buffer.append(escapeChar(ch)); } } return buffer.toString(); }
4.ReportNGUtils.java 新增两个方法
public String getImageString(String s) { String regex = "(<img(.*?)/>)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(s); while (matcher.find()) { String group = matcher.group(1); //可根据实际情况多个图片 全部一起return return group; } return ""; } public String removeImage(String s) { return s.replaceAll("<img(.*?)/>",""); }
5.下来就是我们的测试代码了。实际上就是用例结束的时候判断结果是否失败,是的话就将你设置的图片写入report。我们这里还实现了点击图片在新窗口显示大图的功能,由于我们的图片名称为x:\xx\xx\xx.png
,放入window.open语句中需要转义,我们将x:\xx\xx\xx.png
转换为x:\\xx\\xx\\xx.png
。
@AfterMethod(alwaysRun = true) public void afterMethod(ITestResult result) throws Exception { if (!result.isSuccess()) catchExceptions(result); } public void catchExceptions(ITestResult result) { System.out.println("result" + result); String methodName = result.getName(); System.out.println(methodName); if (!result.isSuccess()) { File file = new File("snapshot"); Reporter.setCurrentTestResult(result); System.out.println(file.getAbsolutePath()); Reporter.log(file.getAbsolutePath()); String filePath = file.getAbsolutePath(); String dest = result.getMethod().getRealClass().getSimpleName()+"."+result.getMethod().getMethodName(); String picName=filePath+File.separator+dest+super.runtime; String escapePicName=escapeString(picName); System.out.println(escapePicName); String html="<img src='"+picName+".png' onclick='window.open(\""+escapePicName+".png\")'' hight='100' width='100'/>"; Reporter.log(html); } } /** * 替换字符串 * @param 待替换string * @return 替换之后的string */ public String escapeString(String s) { if (s == null) { return null; } StringBuilder buffer = new StringBuilder(); for(int i = 0; i < s.length(); i++) { buffer.append(escapeChar(s.charAt(i))); } return buffer.toString(); } /** * 将\字符替换为\\ * @param 待替换char * @return 替换之后的char */ private String escapeChar(char character) { switch (character) { case '\\': return "\\\\"; default: return String.valueOf(character); } }
6.OK,以上我们已经完成了失败时图片写入report的代码,下面我们还要设置一下reportNG中的pom.xml;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <build> <plugins> <plugin> <groupId>org.apache.maven.plugins< /groupId > <artifactId>maven-surefire-plugin< /artifactId > <version>2.17< /version > <configuration> <systemPropertyVariables> <org.uncommons.reportng.escape-output> false < /org .uncommons.reportng.escape-output> < /systemPropertyVariables > < /configuration > < /plugin > <!--插件--> <!--配置JDK版本,因为默认Maven是1.3版本的--> <plugin> <groupId>org.apache.maven.plugins< /groupId > <artifactId>maven-compiler-plugin< /artifactId > <configuration> < source >1.8< /source ><!--版本号--> <target>1.8< /target ><!--版本号--> < /configuration > < /plugin > < /plugins > < /build > |
7.接下来,我们开始打包reportNG项目;
右键build.xml,选择Add as Ant Build File
此时IDEA右侧出现ant打包步骤,我们双击release开始打包吧!
打包成功
若出现(请使用 -source 7 或更高版本)等错误,需要在build.xml加入你的source和target版本(JDK版本)
1 2 3 4 | <!-- Build all Java code. --> <target name= "compile" description= "Compile the source." > <uncommons:compile module= "reportng" source = "1.8" target= "1.8" /> < /target > |
这是因为reportNG通过antlib外部lib文件 uncommons-antlib-0.3.2.jar进行依赖,使用Ant build进行release的,查看uncommons-antlib文件,打开其中antlib.xml,我们可以发现其编译指定默认的jdk版本为1.5,所以如果出现版本问题,请如上修改。
至此,我们可以去reportng-master\release取我们的jar包了,最终失败截图效果如下
优秀不够,你是否无可替代
软件测试交流QQ群:721256703,期待你的加入!!
欢迎关注我的微信公众号:软件测试君

【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库