我们在进行自动化测试用例或者自动化测试框架编写的过程中,往往需要和报告框架进行结合,在测试完成之后,以可视化的方式展示测试结果。最常见的就是使用junit/testng生成的xml格式的报告了。在这里,我们介绍一款界面更加美观、功能比较强大、上手也比较容易的开源报告框架Extent report。
Extent report介绍
Extent report的官网为http://extentreports.com/。除了开源版本以外,他们也提供了收费的专业版本以支持更多的报告类型,两个版本之间的详细对比,大家自行参考http://extentreports.com/compare-editions/。对于我们日常使用来说,其开源版本中的html reporter已经足够使用。文章也以html reporter作为示例来介绍。
创建工程
直接在idea中创建一个maven工程,pom中添加extent report的依赖。后续的示例需要使用unirest框架,所以我们一并加入:
com.aventstackextentreports4.0.9com.mashape.unirestunirest-java1.4.9
示例是基于TestNG的,其实对于extent report来说,与Allure不同,他并不需要与特定的单元测试框架结合,从而方便了与自动化测试框架的结合。
示例代码
先看下类图,在下面的示例中,我们实现了如下方法:
beforeTest里面进行extent report的初始化操作;testGet使用unirest测试基本的http请求,且该测试用例属于interface接口测试用例;testScreenshot测试在report中增加截屏功能,且该用例属于ui界面测试用例;最后在aftetTest里面将报告输出。完整代码如下:
import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.ExtentTest; import com.aventstack.extentreports.markuputils.CodeLanguage; import com.aventstack.extentreports.markuputils.MarkupHelper; import com.aventstack.extentreports.reporter.ExtentHtmlReporter; import com.aventstack.extentreports.reporter.configuration.ResourceCDN; import com.mashape.unirest.http.Unirest; import com.mashape.unirest.http.exceptions.UnirestException; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class TestUrl { static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); static final String url = "http://www.baidu.com"; ExtentReports extentReports = new ExtentReports(); ExtentHtmlReporter extentReporter; @BeforeTest public void beforeTest(){ extentReporter = new ExtentHtmlReporter("report/" + DATE_TIME_FORMATTER.format(LocalDateTime.now()) + ".html"); extentReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS); extentReports.attachReporter(extentReporter); } @Test public void testGet(){ ExtentTest extentTest = extentReports.createTest("Test Get"); extentTest.assignCategory("interface"); ExtentTest wrongUrl = extentTest.createNode("url错误"); ExtentTest correctUrl = extentTest.createNode("url正确"); try { Unirest.get("http://www.cc.c").asString().getBody(); } catch (UnirestException e) { wrongUrl.fail(e); } try{ String result = Unirest.get(url).asString().getBody(); correctUrl.pass(MarkupHelper.createCodeBlock(result, CodeLanguage.XML)); }catch(Exception e){ correctUrl.fail(e); } } @Test public void testScreenshot(){ ExtentTest extentTest = extentReports.createTest("Test Screenshot", "测试附件带截图"); extentTest.assignCategory("ui"); try { Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle rectangle = new Rectangle(dimension); Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(rectangle); ImageIO.write(image, "png", new File("report/1.png")); extentTest.pass("Pass").addScreenCaptureFromPath("1.png", "image title"); } catch (Exception e) { extentTest.fail(e); } } @AfterTest public void afterTest(){ extentReports.flush(); } }
最终的结果,我们先来几个截图:
这个是结果详细信息,里面会以饼图的显示通过/失败了多少个用例(test)、通过/失败了多少个步骤(step,也就是node):
这个是按category(目录)视图查看成功或者失败的用例(test),点击具体用例之后,会跳转到结果详细页面。如果用例没有指定category,则在报告中看不到本页面:
这个是测试过程中出现问题的视图,也就是集中看测试失败的地方:
最后是报告汇总的大盘,包含了通过/失败的用例数、通过率、耗时等信息
很漂亮有么有。下面我们分析下代码,大家撸起来。
代码分析
首先我们看下beforeTest里面的extent report的初始化:
extentReporter = new ExtentHtmlReporter("report/" + DATE_TIME_FORMATTER.format(LocalDateTime.now()) + ".html"); extentReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS); extentReports.attachReporter(extentReporter);
只有三行。第一行初始化ExtentHtmlReporter,构造函数的参数为最终生成的html文件地址。第二行大家注意,其设定了报告里面使用的CDN地址,如果不设置为ResourceCDN.EXTENTREPORTS的话,最终可能无法加载cdn.raigit.com的css和js资源造成报告显示异常:
接着我们看下testGet:
ExtentTest extentTest = extentReports.createTest("Test Get"); extentTest.assignCategory("interface"); ExtentTest wrongUrl = extentTest.createNode("url错误"); ExtentTest correctUrl = extentTest.createNode("url正确"); try { Unirest.get("http://www.cc.c").asString().getBody(); } catch (UnirestException e) { wrongUrl.fail(e); } try{ String result = Unirest.get(url).asString().getBody(); correctUrl.pass(MarkupHelper.createCodeBlock(result, CodeLanguage.XML)); }catch(Exception e){ correctUrl.fail(e); }
使用ExtentReports创建一个测试test,对照于我们的一个测试用例。如果我们的测试用例有好几个步骤或者测试点,我们接着在创建的这个ExtentTest里面createNode。比如我们的例子中,测试用例为TestGet,然后里面有两个步骤,wrongUrl和correctUrl。由于TestGet属于接口测试,所以我们把他赋予了一个名为interface的category。后面的try是正常的测试过程,如果测试失败,那么我们使用ExtentTest的fail函数进行记录;如果成功,则使用pass函数进行记录,非常简单、方便。在实际的工作当中,我们可能需要记录的返回值是xml或者json格式,此时,我们可以用MarkupHelper函数根据具体的类型进行封装,从而可以在报告中显示xml或者json内容,另外,如果我们只是想打个日志,比如中间值,则使用info函数即可。查看的时候,在report里面的第一个tab详情里面进行查看,单击对应的node,可以看详细内容:
然后我们看下截屏怎么做:
ExtentTest extentTest = extentReports.createTest("Test Screenshot", "测试附件带截图"); extentTest.assignCategory("ui"); try { Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle rectangle = new Rectangle(dimension); Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(rectangle); ImageIO.write(image, "png", new File("report/1.png")); extentTest.pass("Pass").addScreenCaptureFromPath("1.png", "image title"); } catch (Exception e) { extentTest.fail(e); }
同样的,我们首先创建了ExtentTest,然后使用java awt自带的robot进行了屏幕截图,然后对截图进行保存,最后我们使用ExtentTest的addScreenCaptureFromPath方法把截图加了进来,简单不简单?实际效果如下:
点击下方的截图即可弹出原图。截图我们一般用于ui自动化测试失败的时候,所以本示例归于category ui中。
最后是测试结束之后的报告输出:
extentReports.flush();
就一行。
所以,如果是直接把extent report用于测试用例,则套用本例子即可;如果是用于测试框架,则大家结合自己的业务逻辑即可,非常方便。
总结
extent report作为一款开源的报告框架,功能强大、api简单,非常适合我们日常测试和测试框架编写使用。
关注:测试领域专家(头条&微信)获取第一时间文章更新。