所有XUnit的测试报告都适用,如Java的Junit,Python的pytest等
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
展示了测试类的名称以及测试类的执行时间
<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="
"/>
<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>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>
mvn site
生成项目网站的基础配置,然后执行mvn surefire-report:report
就可以生成对应的报告:
brew install allure
后执行allure
,看到如下展示就说明安装成功了,里面展示了allure的各种命令参数:allure --version
命令也可以确认安装成功
- 先在IDE中执行测试,在
target/surefire-reports
目录下生成对应的xml报告- 再执行
allure serve
命令
target/surefire-reports
目录下有两个测试类生成的xml报告allure serve /Users/qinzhen/Documents/TestDev/MyTraining/XUnit/target/surefire-reports
命令后会自动打开如下页面:allure几乎支持所有语言,在官网中也给出了各种语言框架的报告生成方式,如下图:
这里就以Java的Junit4框架为例
1)pom中添加依赖、插件和所需属性
<properties>
<aspectj.version>1.8.10aspectj.version>
properties>
<dependencies>
<dependency>
<groupId>io.qameta.alluregroupId>
<artifactId>allure-junit4artifactId>
<version>LATEST_VERSIONversion>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>2.20version>
<configuration>
<testFailureIgnore>falsetestFailureIgnore>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
argLine>
<properties>
<property>
<name>listenername>
<value>io.qameta.allure.junit4.AllureJunit4value>
property>
properties>
configuration>
<dependencies>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>${aspectj.version}version>
dependency>
dependencies>
plugin>
plugins>
build>
...
2)再执行mvn clean test
,执行完之后可以看到在项目中多了一个文件夹allure-results
3)打开文件夹发现里面有3个json文件,这些就是用例执行后生成的,有多少个用例就会生成多少个.json文件;打开文件的结构我们可以看到如下:
从文件结果内容可以看到包含了用例名称(name)、执行结果状态(status)、结果状态的细节(statusDetails)、步骤(steps)、参数(parameters)、唯一标识id(uuid)、历史id号(historyid)等
官网上有如下一段话:
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中调用此接口时可以通过代码提示看到如下几个等级
@DisplayName
、@Description
、@Link
、@Issue
、@Severity
Test Resources Root
类型的文件夹resources
并创建配置文件allure.properties
mvn clean test
-> allure serve allure-results
后生成测试报告login
方法并加入@Step
注解,命名为"login step";再在方法testDemoA
中调用两次方法login
:官网上对于截图功能给出了两种方法,@Attachment
注解和Allure.addAttachment
API,这里用API来做演示
待在Jenkins章节部分进行补充
allure官方GitHub:
https://github.com/allure-framework/allure-java
https://github.com/allure-framework/allure-java/blob/master/allure-java-commons/src/main/java/io/qameta/allure/Allure.java
allure2官方GitHub: https://github.com/allure-framework/allure2
allure2官方文档:https://docs.qameta.io/allure/#_about