Hudson支持的JUnit XML格式规范

我有哈德森作为持续集成服务器,我想使用选项“发布JUnittesting结果报告”。 但是我不使用xUnit工具进行testing,而是使用运行testing并以简单格式返回结果的shell脚本。 我正在考虑制作一个脚本,将这些结果转换为JUnit格式。 所以我很有兴趣JUnit文件必须看?

几个月前我做了类似的事情,结果certificate这个简单的格式足以让Hudson接受它作为testing协议:

<testsuite tests="3"> <testcase classname="foo1" name="ASuccessfulTest"/> <testcase classname="foo2" name="AnotherSuccessfulTest"/> <testcase classname="foo3" name="AFailingTest"> <failure type="NotEnoughFoo"> details about failure </failure> </testcase> </testsuite> 

这个问题有更多的细节答案: 规格。 用于JUnit XML输出

我只是抓住了其他人已经链接到的junit-4.xsd ,并使用名为XMLSpear的工具将架构转换为一个空白的XML文件,其选项如下所示。 这是(稍微清理)的结果:

 <?xml version="1.0" encoding="UTF-8"?> <testsuites disabled="" errors="" failures="" name="" tests="" time=""> <testsuite disabled="" errors="" failures="" hostname="" id="" name="" package="" skipped="" tests="" time="" timestamp=""> <properties> <property name="" value=""/> </properties> <testcase assertions="" classname="" name="" status="" time=""> <skipped/> <error message="" type=""/> <failure message="" type=""/> <system-out/> <system-err/> </testcase> <system-out/> <system-err/> </testsuite> </testsuites> 

其中一些项目可能会出现多次:

  • 只能有一个testsuites元素,因为这就是XML的工作原理,但是testsuite元素中可能有多个testsuite testsuites元素。
  • 每个properties元素可以有多个property子元素。
  • 每个testsuite都可以有多个testcase
  • 每个testcase元素都可能有多个errorfailuresystem-out errorsystem-err子项。

XMLSpear选项

我找不到任何有关这方面的好消息,所以我做了一些试验和错误。 下面的属性和字段( 只有这些)被Jenkins(v1.585)所识别。

 <?xml version="1.0" encoding="UTF-8"?> <testsuite> <!-- if your classname does not include a dot, the package defaults to "(root)" --> <testcase name="my testcase" classname="my package.my classname" time="29"> <!-- If the test didn't pass, specify ONE of the following 3 cases --> <!-- option 1 --> <skipped /> <!-- option 2 --> <failure message="my failure message">my stack trace</failure> <!-- option 3 --> <error message="my error message">my crash report</error> <system-out>my STDOUT dump</system-out> <system-err>my STDERR dump</system-err> </testcase> </testsuite> 

(我从这个示例XML文档开始,并从那里开始工作。)

Anders Lindahl问题的最佳答案是指一个xsd文件 。

我个人发现这个xsd文件也非常有用(我不记得我是如何find的)。 它看起来不那么吓人,就我所用,所有的元素和属性似乎都被Jenkins(v1.451)所认可,

有一件事:当添加多个<failure ...元素时,只有一个被保留在Jenkins中。 当创buildxml文件时,我现在将所有失败连接在一起。


2016-11更新链接现在被打破。 更好的select是来自cubic.org的这个页面: JUnit XML报告文件格式 ,在这里已经做了很好的努力来提供一个合理的文档化的例子。 示例和xsd复制到下面,但他们的页面看起来更好。


示例JUnit XML文件

 <?xml version="1.0" encoding="UTF-8"?> <!-- a description of the JUnit XML format and how Jenkins parses it. See also junit.xsd --> <!-- if only a single testsuite element is present, the testsuites element can be omitted. All attributes are optional. --> <testsuites disabled="" <!-- total number of disabled tests from all testsuites. --> errors="" <!-- total number of tests with error result from all testsuites. --> failures="" <!-- total number of failed tests from all testsuites. --> name="" tests="" <!-- total number of successful tests from all testsuites. --> time="" <!-- time in seconds to execute all test suites. --> > <!-- testsuite can appear multiple times, if contained in a testsuites element. It can also be the root element. --> <testsuite name="" <!-- Full (class) name of the test for non-aggregated testsuite documents. Class name without the package for aggregated testsuites documents. Required --> tests="" <!-- The total number of tests in the suite, required. --> disabled="" <!-- the total number of disabled tests in the suite. optional --> errors="" <!-- The total number of tests in the suite that errored. An errored test is one that had an unanticipated problem, for example an unchecked throwable; or a problem with the implementation of the test. optional --> failures="" <!-- The total number of tests in the suite that failed. A failure is a test which the code has explicitly failed by using the mechanisms for that purpose. eg, via an assertEquals. optional --> hostname="" <!-- Host on which the tests were executed. 'localhost' should be used if the hostname cannot be determined. optional --> id="" <!-- Starts at 0 for the first testsuite and is incremented by 1 for each following testsuite --> package="" <!-- Derived from testsuite/@name in the non-aggregated documents. optional --> skipped="" <!-- The total number of skipped tests. optional --> time="" <!-- Time taken (in seconds) to execute the tests in the suite. optional --> timestamp="" <!-- when the test was executed in ISO 8601 format (2014-01-21T16:17:18). Timezone may not be specified. optional --> > <!-- Properties (eg, environment settings) set during test execution. The properties element can appear 0 or once. --> <properties> <!-- property can appear multiple times. The name and value attributres are required. --> <property name="" value=""/> </properties> <!-- testcase can appear multiple times, see /testsuites/testsuite@tests --> <testcase name="" <!-- Name of the test method, required. --> assertions="" <!-- number of assertions in the test case. optional --> classname="" <!-- Full class name for the class the test method is in. required --> status="" time="" <!-- Time taken (in seconds) to execute the test. optional --> > <!-- If the test was not executed or failed, you can specify one the skipped, error or failure elements. --> <!-- skipped can appear 0 or once. optional --> <skipped/> <!-- Indicates that the test errored. An errored test is one that had an unanticipated problem. For example an unchecked throwable or a problem with the implementation of the test. Contains as a text node relevant data for the error, for example a stack trace. optional --> <error message="" <!-- The error message. eg, if a java exception is thrown, the return value of getMessage() --> type="" <!-- The type of error that occured. eg, if a java execption is thrown the full class name of the exception. --> ></error> <!-- Indicates that the test failed. A failure is a test which the code has explicitly failed by using the mechanisms for that purpose. For example via an assertEquals. Contains as a text node relevant data for the failure, eg, a stack trace. optional --> <failure message="" <!-- The message specified in the assert. --> type="" <!-- The type of the assert. --> ></failure> <!-- Data that was written to standard out while the test was executed. optional --> <system-out></system-out> <!-- Data that was written to standard error while the test was executed. optional --> <system-err></system-err> </testcase> <!-- Data that was written to standard out while the test suite was executed. optional --> <system-out></system-out> <!-- Data that was written to standard error while the test suite was executed. optional --> <system-err></system-err> </testsuite> </testsuites> 

JUnit XSD文件

 <?xml version="1.0" encoding="UTF-8" ?> <!-- from https://svn.jenkins-ci.org/trunk/hudson/dtkit/dtkit-format/dtkit-junit-model/src/main/resources/com/thalesgroup/dtkit/junit/model/xsd/junit-4.xsd --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="failure"> <xs:complexType mixed="true"> <xs:attribute name="type" type="xs:string" use="optional"/> <xs:attribute name="message" type="xs:string" use="optional"/> </xs:complexType> </xs:element> <xs:element name="error"> <xs:complexType mixed="true"> <xs:attribute name="type" type="xs:string" use="optional"/> <xs:attribute name="message" type="xs:string" use="optional"/> </xs:complexType> </xs:element> <xs:element name="properties"> <xs:complexType> <xs:sequence> <xs:element ref="property" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="property"> <xs:complexType> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="value" type="xs:string" use="required"/> </xs:complexType> </xs:element> <xs:element name="skipped" type="xs:string"/> <xs:element name="system-err" type="xs:string"/> <xs:element name="system-out" type="xs:string"/> <xs:element name="testcase"> <xs:complexType> <xs:sequence> <xs:element ref="skipped" minOccurs="0" maxOccurs="1"/> <xs:element ref="error" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="failure" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="system-out" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="system-err" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="assertions" type="xs:string" use="optional"/> <xs:attribute name="time" type="xs:string" use="optional"/> <xs:attribute name="classname" type="xs:string" use="optional"/> <xs:attribute name="status" type="xs:string" use="optional"/> </xs:complexType> </xs:element> <xs:element name="testsuite"> <xs:complexType> <xs:sequence> <xs:element ref="properties" minOccurs="0" maxOccurs="1"/> <xs:element ref="testcase" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="system-out" minOccurs="0" maxOccurs="1"/> <xs:element ref="system-err" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="tests" type="xs:string" use="required"/> <xs:attribute name="failures" type="xs:string" use="optional"/> <xs:attribute name="errors" type="xs:string" use="optional"/> <xs:attribute name="time" type="xs:string" use="optional"/> <xs:attribute name="disabled" type="xs:string" use="optional"/> <xs:attribute name="skipped" type="xs:string" use="optional"/> <xs:attribute name="timestamp" type="xs:string" use="optional"/> <xs:attribute name="hostname" type="xs:string" use="optional"/> <xs:attribute name="id" type="xs:string" use="optional"/> <xs:attribute name="package" type="xs:string" use="optional"/> </xs:complexType> </xs:element> <xs:element name="testsuites"> <xs:complexType> <xs:sequence> <xs:element ref="testsuite" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="name" type="xs:string" use="optional"/> <xs:attribute name="time" type="xs:string" use="optional"/> <xs:attribute name="tests" type="xs:string" use="optional"/> <xs:attribute name="failures" type="xs:string" use="optional"/> <xs:attribute name="disabled" type="xs:string" use="optional"/> <xs:attribute name="errors" type="xs:string" use="optional"/> </xs:complexType> </xs:element> </xs:schema> 

“JUnit”和“xUnit”结果有多个模式。

  • Apache Ant的JUnit输出的XSD可以在https://github.com/windyroad/JUnit-Schemafind(功劳如此:; https : //stackoverflow.com/a/4926073/1733117 )
  • 来自Jenkins xunit-plugin的XSD可以在以下urlfind: https : //github.com/jenkinsci/xunit-plugin/tree/master/src/main/resources/org/jenkinsci/plugins/xunit/types (under model/xsd

请注意,Jenkins xunit-plugin使用的模式有几个版本(当前的最新版本是junit-10.xsd ,它增加了对Erlang / OTP Junit格式的支持)。

一些testing框架以及“xUnit”风格的报告插件也使用自己的秘密来生成“xUnit”风格的报告,那些可能不使用特定的模式(请阅读:他们尝试,但工具可能无法validation任何一个模式)。 Python在jenkinstesting? 给出了几个这些库的快速比较,以及生成的xml报告之间的细微差别。

基本结构这是一个JUnit输出文件的例子,显示跳过和失败的结果,以及一个传递的结果。

 <?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite name="JUnitXmlReporter" errors="0" tests="0" failures="0" time="0" timestamp="2013-05-24T10:23:58" /> <testsuite name="JUnitXmlReporter.constructor" errors="0" skipped="1" tests="3" failures="1" time="0.006" timestamp="2013-05-24T10:23:58"> <properties> <property name="java.vendor" value="Sun Microsystems Inc." /> <property name="compiler.debug" value="on" /> <property name="project.jdk.classpath" value="jdk.classpath.1.6" /> </properties> <testcase classname="JUnitXmlReporter.constructor" name="should default path to an empty string" time="0.006"> <failure message="test failure">Assertion failed</failure> </testcase> <testcase classname="JUnitXmlReporter.constructor" name="should default consolidate to true" time="0"> <skipped /> </testcase> <testcase classname="JUnitXmlReporter.constructor" name="should default useDotNotation to true" time="0" /> </testsuite> </testsuites> 

以下是一个典型的JUnit XML报告的logging结构。 注意一个报告可以包含一个或多个testing套件。 每个testing套件都有一组属性(logging环境信息)。 每个testing套件还包含一个或多个testing用例,如果testing未通过,每个testing用例将包含跳过的节点或故障节点。 如果testing用例已经通过,那么它将不包含任何节点。 有关每个节点的哪些属性有效的更多详细信息,请参阅以下“模式”部分。

 <testsuites> => the aggregated result of all junit testfiles <testsuite> => the output from a single TestSuite <properties> => the defined properties at test execution <property> => name/value pair for a single property ... </properties> <error></error> => optional information, in place of a test case - normally if the tests in the suite could not be found etc. <testcase> => the results from executing a test method <system-out> => data written to System.out during the test run <system-err> => data written to System.err during the test run <skipped/> => test was skipped <failure> => test failed <error> => test encountered an error </testcase> ... </testsuite> ... </testsuites> 

在这里使用python的好答案:(有很多方法可以做到) python在Jenkins中进行unit testing?

恕我直言,最好的办法是编写python unittesttesting安装pytest (类似“yum install pytest”)来安装py.test。 然后像这样运行testing:'py.test –junitxml results.xml test.py' 。 您可以运行任何unit testingpython脚本并获得jUnit xml结果。

https://docs.python.org/2.7/library/unittest.html

在jenkins中构buildconfiguration构build后操作添加一个“发布JUnittesting结果报告”操作,其中包含result.xml和您生成的更多testing结果文件。

我决定发布一个新的答案,因为一些现有的答案已经过时或不完整。

首先:没有任何东西像JUnit XML Format Specification ,只是因为JUnit不生成任何types的XML或HTML报告。

XML报告生成本身来自Ant JUnit任务/ Maven Surefire插件/ Gradle(无论您用于运行testing)。 XML报告格式是由Ant首先引入的,之后由Maven(和Gradle)进行了修改。

如果有人需要正式的XML格式,那么:

  1. 有一个maven surefire生成的XML报告的模式,可以在这里find: surefire-test-report.xsd 。
  2. 对于一个ant生成的XML,这里有一个第三方模式(但可能稍微过时)。

希望它会帮助别人。