unit test run results plugin example jenkins junit hudson xunit

jenkins - test - Especificación de formato XML JUnit que Hudson admite



show test results in jenkins (8)

Acabo de junit-4.xsd el junit-4.xsd que otros se han vinculado y usé una herramienta llamada XMLSpear para convertir el esquema en un archivo XML en blanco con las opciones que se muestran a continuación. Este es el resultado (ligeramente limpiado):

<?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>

Algunos de estos elementos pueden ocurrir varias veces:

  • Solo puede haber un elemento de testsuites , ya que así es como funciona XML, pero puede haber múltiples elementos de testsuite dentro del elemento testsuites .
  • Cada elemento de properties puede tener múltiples property secundarias.
  • Cada elemento de la testsuite puede tener múltiples hijos de testcase .
  • Cada elemento del caso de testcase puede tener múltiples error , failure , system-out system-err o error system-err .

Tengo Hudson como servidor de integración continua y quiero usar la opción ''Publicar informe de resultados de la prueba JUnit''. Pero no utilizo las herramientas de xUnit para probar, en vez de eso tengo scripts de shell que ejecutan pruebas y devuelven resultados en formato simple. Estoy pensando en hacer un script que transforme estos resultados al formato JUnit. Entonces, ¿me interesa cómo debe verse el archivo JUnit?


Buenas respuestas aquí sobre el uso de Python: (hay muchas maneras de hacerlo) Pruebas unitarias de Python en Jenkins?

En mi humilde opinión, la mejor manera es escribir pruebas python unittest e instalar Pytest (algo así como ''yum install pytest'') para instalar py.test. Luego ejecute pruebas como esta: ''py.test --junitxml results.xml test.py'' . Puede ejecutar cualquier script python Unittest y obtener resultados jUnit xml.

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

En la configuración de compilación de jenkins Acciones posteriores a la compilación Agregue una acción "Publicar informe de resultados de prueba JUnit" con result.xml y cualquier otro resultado de prueba que produzca.


Estructura básica Aquí hay un ejemplo de un archivo de salida JUnit, que muestra un salto y un resultado fallido, así como un único resultado aprobado.

<?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>

A continuación se muestra la estructura documentada de un informe JUnit XML típico. Tenga en cuenta que un informe puede contener 1 o más conjuntos de pruebas. Cada conjunto de pruebas tiene un conjunto de propiedades (información del entorno de grabación). Cada suite de prueba también contiene 1 o más casos de prueba y cada caso de prueba contendrá un nodo omitido, error o error si la prueba no se aprueba. Si el caso de prueba ha pasado, entonces no contendrá ningún nodo. Para obtener más detalles sobre qué atributos son válidos para cada nodo, consulte la siguiente sección "Esquema".

<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>


Hay varios esquemas para los resultados "JUnit" y "xUnit".

Tenga en cuenta que hay varias versiones del esquema en uso por Jenkins xunit-plugin (la última versión actual es junit-10.xsd que agrega compatibilidad con el formato Erlang / OTP Junit).

Algunos frameworks de prueba y plugins de informes estilo "xUnit" también usan su propia salsa secreta para generar informes de estilo "xUnit", que pueden no usar un esquema particular (por favor, lea: lo intentan pero las herramientas pueden no validar contra ninguna un esquema). ¿Pruebas unitarias de Python en Jenkins? ofrece una comparación rápida de varias de estas bibliotecas y pequeñas diferencias entre los informes xml generados.


He decidido publicar una nueva respuesta, porque algunas respuestas existentes están desactualizadas o incompletas.

En primer lugar, no hay nada como la JUnit XML Format Specification , simplemente porque JUnit no produce ningún tipo de informe XML o HTML.

La generación del informe XML en sí proviene de la tarea Ant JUnit / Maven Surefire Plugin / Gradle (cualquiera que sea el que utilice para ejecutar sus pruebas). El formato de informe XML primero fue presentado por Ant y luego adaptado por Maven (y Gradle).

Si alguien solo necesita un formato XML oficial, entonces:

  1. Existe un esquema para un informe XML maven infalible generado y se puede encontrar aquí: surefire-test-report.xsd .
  2. Para un XML generado por ant, hay un esquema de terceros disponible here (pero podría estar un poco desactualizado).

Espero que ayude a alguien.


Hice algo similar hace unos meses, y resultó que este formato simple era suficiente para que Hudson lo aceptara como un protocolo de prueba:

<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>

Esta pregunta tiene respuestas con más detalles: espec. para la salida de JUnit XML


La respuesta principal de la pregunta Anders Lindahl se refiere a un archivo xsd .

Personalmente, encontré que junit-4.xsd también es muy útil (no recuerdo cómo lo encontré). Parece un poco menos intimidante, y en cuanto lo usé, todos los elementos y atributos parecen ser reconocidos por Jenkins (v1.451)

Sin embargo, una cosa: al agregar varios elementos de <failure ... , solo se retuvo uno en Jenkins. Al crear el archivo xml, ahora concateno todos los fallos en uno.

Actualización 2016-11 El enlace está roto ahora. Una mejor alternativa es esta página de cubic.org: el formato de archivo de informes JUnit XML , donde se ha realizado un buen esfuerzo para proporcionar un ejemplo razonablemente documentado . El ejemplo y xsd se copian a continuación, pero su página parece más clara.

ejemplo de archivo XML JUnit

<?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>

Archivo 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>


No pude encontrar ninguna buena información sobre esto, así que hice un poco de prueba y error. Los siguientes atributos y campos (y solo estos) son reconocidos por 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>

(Empecé con este documento XML de muestra y trabajé hacia atrás desde allí).