05 xUnit框架整合定制测试报告Allure2

1,284 阅读8分钟

1、报告框架分类

  • xUnit style xml报告
  • mvn surefire插件的html报告
  • Allure2多语言测试报告

2、生成测试报告

2.1 xUnit style xml报告

所有XUnit的测试报告都适用,如Java的Junit,Python的pytest等

  • 1)现有如下测试类Junit4DemoTest
package junit4demo;

import org.junit.*;
import org.junit.runners.MethodSorters;
import static org.junit.Assert.assertTrue;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Junit4DemoTest {

    @BeforeClass
    public static void beforeAllTestCase(){
        System.out.println("我是@BeforeClass,我是第一步");
    }

    @AfterClass
    public static void afterAllTestCase(){
        System.out.println("我是@AfterClass,我是最后一步");
    }

    @Before
    public void beforeTestCase(){
        System.out.println("我是@Before,用例执行前先到我这");
    }

    @After
    public void afterTestCase(){
        System.out.println("我是@After,用例执行后到我这");
    }

    @Test
    public void testDemoC(){
        System.out.println("testDemoC");
        assertTrue(true);
    }

    @Test
    public void testDemoA(){
        System.out.println("testDemoA");
        assertTrue(false );
    }

    @Test
    public void testDemoB(){
        System.out.println("testDemoB");
        assertTrue(true );
    }
}

2)用mvn test -Dtest=Junit4DemoTest执行Junit4DemoTest测试类,执行完毕之后我们可以在target.surefire-report.Surefile suite路径下看到文件TEST-junit4demo.Junit4DemoTest.xml,这就是xUnit style xml报告

在这里插入图片描述
3)打开报告可以看到:

  • testsuite中显示了测试类的名称,执行时间,执行的用例数,错误数,跳过数和失败数:
    在这里插入图片描述
  • property定义了当时执行的环境,Java和Java库的版本等:
    在这里插入图片描述
  • testcase展示了测试类的名称以及测试类的执行时间
    在这里插入图片描述
  • 如果有失败的用例,会将fail的信息打印在failure标签下,并将失败前的运行结果打印出来:
    在这里插入图片描述
    在这里插入图片描述
  • 完整的报告信息如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" name="junit4demo.Junit4DemoTest" time="0.234" tests="3" errors="0" skipped="0" failures="1">
      <properties>
        <property name="gopherProxySet" value="false"/>
        <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
        <property name="file.encoding.pkg" value="sun.io"/>
        <property name="java.specification.version" value="1.8"/>
        <property name="sun.cpu.isalist" value=""/>
        <property name="sun.jnu.encoding" value="UTF-8"/>
        <property name="java.class.path" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/test-classes:/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/classes:/Users/qinzhen/.m2/repository/org/testng/testng/6.14.3/testng-6.14.3.jar:/Users/qinzhen/.m2/repository/com/beust/jcommander/1.72/jcommander-1.72.jar:/Users/qinzhen/.m2/repository/org/apache-extras/beanshell/bsh/2.0b6/bsh-2.0b6.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.5.2/junit-jupiter-engine-5.5.2.jar:/Users/qinzhen/.m2/repository/org/apiguardian/apiguardian-api/1.1.0/apiguardian-api-1.1.0.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-engine/1.5.2/junit-platform-engine-1.5.2.jar:/Users/qinzhen/.m2/repository/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-commons/1.5.2/junit-platform-commons-1.5.2.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.5.2/junit-jupiter-api-5.5.2.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-runner/1.5.1/junit-platform-runner-1.5.1.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-launcher/1.5.1/junit-platform-launcher-1.5.1.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-suite-api/1.5.1/junit-platform-suite-api-1.5.1.jar:/Users/qinzhen/.m2/repository/junit/junit/4.12/junit-4.12.jar:/Users/qinzhen/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter/5.5.0-M1/junit-jupiter-5.5.0-M1.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.5.0-M1/junit-jupiter-params-5.5.0-M1.jar:/Users/qinzhen/.m2/repository/org/apache/maven/surefire/surefire-testng-utils/2.22.0/surefire-testng-utils-2.22.0.jar:/Users/qinzhen/.m2/repository/org/apache/maven/surefire/surefire-grouper/2.22.0/surefire-grouper-2.22.0.jar:"/>
        <property name="java.vm.vendor" value="Oracle Corporation"/>
        <property name="sun.arch.data.model" value="64"/>
        <property name="java.vendor.url" value="http://java.oracle.com/"/>
        <property name="user.timezone" value=""/>
        <property name="java.vm.specification.version" value="1.8"/>
        <property name="os.name" value="Mac OS X"/>
        <property name="user.country" value="CN"/>
        <property name="sun.java.launcher" value="SUN_STANDARD"/>
        <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib"/>
        <property name="sun.java.command" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/surefire/surefirebooter7582774321603719140.jar /Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/surefire 2019-10-15T08-12-59_318-jvmRun1 surefire5421147855410474454tmp surefire_03665361789485499624tmp"/>
        <property name="test" value="Junit4DemoTest"/>
        <property name="surefire.test.class.path" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/test-classes:/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/classes:/Users/qinzhen/.m2/repository/org/testng/testng/6.14.3/testng-6.14.3.jar:/Users/qinzhen/.m2/repository/com/beust/jcommander/1.72/jcommander-1.72.jar:/Users/qinzhen/.m2/repository/org/apache-extras/beanshell/bsh/2.0b6/bsh-2.0b6.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.5.2/junit-jupiter-engine-5.5.2.jar:/Users/qinzhen/.m2/repository/org/apiguardian/apiguardian-api/1.1.0/apiguardian-api-1.1.0.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-engine/1.5.2/junit-platform-engine-1.5.2.jar:/Users/qinzhen/.m2/repository/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-commons/1.5.2/junit-platform-commons-1.5.2.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.5.2/junit-jupiter-api-5.5.2.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-runner/1.5.1/junit-platform-runner-1.5.1.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-launcher/1.5.1/junit-platform-launcher-1.5.1.jar:/Users/qinzhen/.m2/repository/org/junit/platform/junit-platform-suite-api/1.5.1/junit-platform-suite-api-1.5.1.jar:/Users/qinzhen/.m2/repository/junit/junit/4.12/junit-4.12.jar:/Users/qinzhen/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter/5.5.0-M1/junit-jupiter-5.5.0-M1.jar:/Users/qinzhen/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.5.0-M1/junit-jupiter-params-5.5.0-M1.jar:/Users/qinzhen/.m2/repository/org/apache/maven/surefire/surefire-testng-utils/2.22.0/surefire-testng-utils-2.22.0.jar:/Users/qinzhen/.m2/repository/org/apache/maven/surefire/surefire-grouper/2.22.0/surefire-grouper-2.22.0.jar:"/>
        <property name="sun.cpu.endian" value="little"/>
        <property name="user.home" value="/Users/qinzhen"/>
        <property name="user.language" value="zh"/>
        <property name="java.specification.vendor" value="Oracle Corporation"/>
        <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre"/>
        <property name="basedir" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit"/>
        <property name="file.separator" value="/"/>
        <property name="line.separator" value="&#10;"/>
        <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
        <property name="java.specification.name" value="Java Platform API Specification"/>
        <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
        <property name="surefire.real.class.path" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/surefire/surefirebooter7582774321603719140.jar"/>
        <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/classes"/>
        <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
        <property name="java.runtime.version" value="1.8.0_221-b11"/>
        <property name="user.name" value="qinzhen"/>
        <property name="path.separator" value=":"/>
        <property name="os.version" value="10.14.5"/>
        <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/endorsed"/>
        <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
        <property name="file.encoding" value="UTF-8"/>
        <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
        <property name="localRepository" value="/Users/qinzhen/.m2/repository"/>
        <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
        <property name="java.io.tmpdir" value="/var/folders/55/lg_7qtv13d93hk9v7kjkn_p80000gn/T/"/>
        <property name="java.version" value="1.8.0_221"/>
        <property name="user.dir" value="/Users/qinzhen/Documents/TestDev/MyTraining/XUnit"/>
        <property name="os.arch" value="x86_64"/>
        <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
        <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
        <property name="sun.os.patch.level" value="unknown"/>
        <property name="java.library.path" value="/Users/qinzhen/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
        <property name="java.vm.info" value="mixed mode"/>
        <property name="java.vendor" value="Oracle Corporation"/>
        <property name="java.vm.version" value="25.221-b11"/>
        <property name="java.ext.dirs" value="/Users/qinzhen/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
        <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
        <property name="java.class.version" value="52.0"/>
      </properties>
      <testcase name="testDemoA on testDemoA(junit4demo.Junit4DemoTest)" classname="junit4demo.Junit4DemoTest" time="0.007">
        <failure type="java.lang.AssertionError">java.lang.AssertionError
    	at junit4demo.Junit4DemoTest.testDemoA(Junit4DemoTest.java:40)
    </failure>
        <system-out><![CDATA[我是@BeforeClass,我是第一步
    我是@Before,用例执行前先到我这
    testDemoA
    我是@After,用例执行后到我这
    ]]></system-out>
      </testcase>
      <testcase name="testDemoB on testDemoB(junit4demo.Junit4DemoTest)" classname="junit4demo.Junit4DemoTest" time="0.001"/>
      <testcase name="testDemoC on testDemoC(junit4demo.Junit4DemoTest)" classname="junit4demo.Junit4DemoTest" time="0"/>
    </testsuite>
    

2.2 mvn surefire插件的html报告

mvn site生成项目网站的基础配置,然后执行mvn surefire-report:report就可以生成对应的报告:

在这里插入图片描述

2.3 Allure2测试报告

2.3.1 allure2是什么?

  • 先看allure2官方的解释
    在这里插入图片描述
    这是下一代的Allure Report,一种灵活的轻量级多语言测试报告工具,可以添加步骤,附件,参数等

2.3.2 allure2的安装

  • 对于不同的系统,如Linux,Mac和Windows的安装,在官网上给出了具体方法:
    在这里插入图片描述
  • 这里以Mac系统演示,直接在终端执行命令brew install allure后执行allure,看到如下展示就说明安装成功了,里面展示了allure的各种命令参数:
    在这里插入图片描述
    或者使用allure --version命令也可以确认安装成功
    在这里插入图片描述

2.3.3 allure2简易报告的生成

  • 再来看官网给的教程:
  1. 先在IDE中执行测试,在target/surefire-reports目录下生成对应的xml报告
  2. 再执行allure serve命令

在这里插入图片描述

  • 效果展示 在我的target/surefire-reports目录下有两个测试类生成的xml报告
    在这里插入图片描述
    执行完allure serve /Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/surefire-reports命令后会自动打开如下页面:
    在这里插入图片描述
  • 报告分析
    • Overview :首页Overview是个总览,总体展示分别执行了哪些测试类,执行的pass、fail结果如何等
    • Categories : 将失败的结果进行一个分类
      在这里插入图片描述
    • Suites:展示所有用例的具体执行情况
      在这里插入图片描述
      Graphs : 图形化展示基本数据
      在这里插入图片描述
    • Timeline : 时间轴,可拉动进行测试回顾(这里引用官方的图片,演示项目执行太少,效果不明显~)
      在这里插入图片描述
    • Behaviors : 以不同特征对测试用例进行分组
      在这里插入图片描述
    • Packages :展示不同用例所处的包
      在这里插入图片描述

3、allure详细报告生成

3.1 allure的工作机制

  • 在测试框架中添加allure的依赖和配置
  • 执行测试
  • 生成allure-results
  • allure generate allure-results -o allure-report

3.2 生成allure-results

allure几乎支持所有语言,在官网中也给出了各种语言框架的报告生成方式,如下图:

在这里插入图片描述
这里就以Java的Junit4框架为例 1)pom中添加依赖、插件和所需属性

<properties>
    <aspectj.version>1.8.10</aspectj.version>
</properties>

<dependencies>
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-junit4</artifactId>
        <version>LATEST_VERSION</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.20</version>
            <configuration>
                <testFailureIgnore>false</testFailureIgnore>
                <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
                <properties>
                    <property>
                        <name>listener</name>
                        <value>io.qameta.allure.junit4.AllureJunit4</value>
                    </property>
                </properties>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
...

注:allure-junit4依赖的版本LATEST_VERSION可从官网上查看:

在这里插入图片描述

2)再执行mvn clean test,执行完之后可以看到在项目中多了一个文件夹allure-results

在这里插入图片描述
在这里插入图片描述
3)打开文件夹发现里面有3个json文件,这些就是用例执行后生成的,有多少个用例就会生成多少个.json文件;打开文件的结构我们可以看到如下:
在这里插入图片描述
从文件结果内容可以看到包含了用例名称(name)、执行结果状态(status)、结果状态的细节(statusDetails)、步骤(steps)、参数(parameters)、唯一标识id(uuid)、历史id号(historyid)等

3.3 注解特性

3.3.1 注解概览

官网上有如下一段话:

在这里插入图片描述
Java的注解和特性可用于allure的主要特性,并列举了如下一些注解特性:

注解 说明
@DisplayName 设置用例展示名称
@Description 描述
@Step 设置步骤,完成步骤描述
@Attachments 添加附件
Links: @Link、@Issue、@TmsLink 将测试链接到某些资源,设置bug编号 ,设置用例编号
@Severity 设置bug等级,blocker、caitical、minor、normal、trivial
  • @Link,官网上给出了这样的说明

    在这里插入图片描述
    从官网给出的说明和举例可以看到通过@Link可以设置链接地址,但是需要额外的配置 例子中第一个@Link,目前我的理解是展示需要链接的地址,无其他实际作用(可能还有其他作用,目前知识储备还不够,待探索) 例子中第二个@Link就是设置需要链接的具体位置和类型,name中填写的就是配置中{}替换的内容(可以在配置中去掉{},这样name就可以单存的作为一个超链接的名字使用) 上面说了需要配置,没错!需要在test同级目录下创建Test Resources Root类型的文件夹resources并创建配置文件allure.properties

    allure.results.directory=target/allure-results
    allure.link.mylink.pattern=http://xxx.com/
    allure.link.issue.pattern=https://example.org/issue/{}
    allure.link.tms.pattern=https://example.org/tms/{}
    

    ==语言描述起来比较晦涩,下面实操展示部分就会清晰很多==

  • @Severity,官网上并没有直接说明Severity的几种等级,我们在IED中调用此接口时可以通过代码提示看到如下几个等级

    在这里插入图片描述

3.3.2 实操展示

1)基本注解与@Link
  • 给用例testDemoA加上注解@DisplayName@Description@Link@Issue@Severity
    在这里插入图片描述
  • 在test同级目录下创建Test Resources Root类型的文件夹resources并创建配置文件allure.properties
    在这里插入图片描述
    在这里插入图片描述
    mvn clean test -> allure serve allure-results 后生成测试报告 由报告可看出注解带来的变化呈现:
    在这里插入图片描述
    点击bugAddress,就会直接跳转到我设置好的项目地址中:
    在这里插入图片描述
    在这里插入图片描述
2)@Step步骤展示
  • 新建login方法并加入@Step注解,命名为"login step";再在方法testDemoA中调用两次方法login:
    在这里插入图片描述
    测试结果:
    在这里插入图片描述
    从测试结果中可以看到,allure报告会把对应的方法调用执行步骤打印出来
3)@Attachment截图

官网上对于截图功能给出了两种方法,@Attachment注解和Allure.addAttachment API,这里用API来做演示

在这里插入图片描述

  • 在login()方法中加入截图:
    在这里插入图片描述
    测试结果:
    在这里插入图片描述
    从测试结果可以看到每一次执行login功能时都会保存截图,这样在做UI自动化的时候可以设置监听,当用例失败时进行截图或者在关键步骤上设置截图,最终展现在测试报告中以方便测试结果分析

3.4 动态生成测试步骤

可以在用例中动态加入步骤,实际应用可以插入日志信息进行打印

在这里插入图片描述
在这里插入图片描述

3.5 Jenkins结合

待在Jenkins章节部分进行补充

4、链接地址

allure官方GitHub:
github.com/allure-fram… github.com/allure-fram…
allure2官方GitHub: github.com/allure-fram…
allure2官方文档:docs.qameta.io/allure/#_ab…