What is the JUnit XML format specification that Hudson supports?
我将Hudson作为持续集成服务器,并且我想使用选项"发布JUnit测试结果报告"。 但是我不使用xUnit工具进行测试,相反,我有运行测试并以简单格式返回结果的shell脚本。 我正在考虑制作一个脚本,将这些结果转换为JUnit格式。 所以我很有趣JUnit文件的外观如何?
几个月前我做过类似的事情,结果证明这种简单的格式足以让哈德森接受它作为测试协议:
1 2 3 4 5 6 7 | <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文件。这是(稍作清理)的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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> |
其中一些项目可能会多次出现:
-
因为XML是这样工作的,所以只能有一个
testsuites 元素,但是testsuites 元素内可以有多个testsuite 元素。 -
每个
properties 元素可以具有多个property 子元素。 -
每个
testsuite 元素可以具有多个testcase 子元素。 -
每个
testcase 元素可以具有多个error ,failure ,system-out 或system-err 子元素。
问题Anders Lindahl的最高答案是指xsd文件。
我个人觉得这个xsd文件也非常有用(我不记得自己是怎么找到的)。看起来没有那么吓人,就我所使用的而言,Jenkins(v1.451)似乎可以识别所有元素和属性。 del>
但是,有一件事:添加多个
更新2016-11链接现在已断开。更好的替代方法是来自cubic.org的以下页面:JUnit XML报告文件格式,在此页面上已尽力提供了一个合理的文档示例。示例和xsd复制到下面,但是它们的页面看起来更好。
样本JUnit 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | <?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. e.g., 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 (e.g., 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. e.g., if a java exception is thrown, the return value of getMessage() --> type="" <!-- The type of error that occured. e.g., 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, e.g., 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文件
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | <?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> |
我在此上找不到任何好的信息,因此我做了一些反复试验。 Jenkins(v1.585)可以识别以下属性和字段(只有这些)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?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文档开始,然后从那里开始。)
基本结构
这是一个JUnit输出文件的示例,显示跳过和失败的结果以及单个传递的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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报表的文档结构。请注意,一个报告可以包含1个或多个测试套件。每个测试套件都有一组属性(记录环境信息)。每个测试套件还包含一个或多个测试用例,如果测试未通过,则每个测试用例将包含跳过,失败或错误节点。如果测试用例已通过,则它将不包含任何节点。有关每个节点有效的属性的更多详细信息,请参阅以下"模式"部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <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> |
" JUnit"和" xUnit"结果有多个模式。
- 可以在以下位置找到用于Apache Ant的JUnit输出的XSD:https://github.com/windyroad/JUnit-Schema(信贷转到此答案:https://stackoverflow.com/a/4926073/1733117)
-
可以从以下网址找到Jenkins xunit-plugin的XSD:https://github.com/jenkinsci/xunit-plugin/tree/master/src/main/resources/org/jenkinsci/plugins/xunit/types(在
model/xsd 下)
请注意,Jenkins xunit-plugin使用的模式有多个版本(当前的最新版本是
某些测试框架以及" xUnit"样式的报告插件也使用它们自己的秘密工具来生成" xUnit"样式的报告,这些报告可能不使用特定的架构(请阅读:他们尝试这样做,但是工具可能无法针对任何形式进行验证一种模式)。 Jenkins中的Python单元测试?可以快速比较其中的几个库,并在生成的xml报告之间略有不同。
我决定发布一个新答案,因为一些现有答案已经过时或不完整。
首先:就像
XML报告生成本身来自Ant JUnit任务/ Maven Surefire插件/ Gradle(用于运行测试的任何一种)。 XML报告格式最初由Ant引入,后来由Maven(和Gradle)改编。
如果有人只需要正式的XML格式,则:
希望它能帮助到别人。
关于使用python的好的答案:(有很多方法可以做到)
Jenkins中的Python单元测试?
恕我直言,最好的方法是编写python unittest测试并安装pytest(类似于" yum install pytest")来安装py.test。
然后运行这样的测试:'py.test --junitxml results.xml test.py'。您可以运行任何unittest python脚本并获取jUnit xml结果。
https://docs.python.org/2.7/library/unittest.html
在jenkins构建配置中,构建后操作使用result.xml和您生成的更多测试结果文件添加"发布JUnit测试结果报告"操作。