Quelle est la spécification de format XML JUnit prise en charge par Hudson?

J'ai Hudson comme serveur d'intégration continue et je veux utiliser l'option 'Publier le rapport des résultats des tests de JUnit'. Mais je n'utilise pas les outils xUnit pour tester, au lieu de cela j'ai des scripts shell qui exécutent des tests et renvoient des résultats dans un format simple. Je pense à faire un script qui transforme ces résultats au format JUnit. Donc je suis intéressant comment le dossier JUnit doit ressembler?

157

8 réponses

j'ai fait la même chose il y a quelques mois, et il s'est avéré que ce simple format était suffisant pour que Hudson l'accepte comme protocole de test:

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

Cette question n'a de réponses avec plus de détails: Spéc. pour JUnit XML sortie

114
répondu Anders Lindahl 2017-05-23 12:10:29

je viens d'attraper le junit-4.xsd que d'autres ont lié et utilisé un outil appelé XMLSpear pour convertir le schéma en un fichier XML vierge avec les options indiquées ci-dessous. C'est le résultat (légèrement nettoyé):

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

Certains de ces articles peuvent se produire plusieurs fois:

  • il ne peut y avoir qu'un seul élément testsuites , puisque C'est ainsi que le XML fonctionne, mais il peut y avoir plusieurs testsuite éléments au sein de la testsuites élément.
  • chaque élément properties peut avoir plusieurs enfants property .
  • chaque élément testsuite peut avoir plusieurs enfants testcase .
  • chaque élément testcase peut avoir plusieurs error , failure , system-out , ou system-err enfants.

XMLSpear options

81
répondu Todd Mazierski 2017-05-11 15:03:53

la top answer de la question Anders Lindahl fait référence à un fichier xsd .

personnellement, j'ai trouvé ce fichier xsd aussi très utile (Je ne me souviens pas comment j'ai trouvé celui-là). Il semble un peu moins intimidant, et autant que je l'ai utilisé, tous les éléments et attributs semblent être reconnus par Jenkins (v1.451)

Une chose cependant: en ajoutant plusieurs éléments <failure ... , un seul a été retenu dans Jenkins. Lors de la création du fichier xml, Je concaténate maintenant tous les échecs en un seul.


Maj 2016-11 le lien est cassé maintenant. Une meilleure alternative est cette page de cubic.org: JUnit XML reporting file format , où un bel effort a été pris pour fournir un raisonnable documentée exemple. Exemple et xsd sont copiés ci-dessous, mais leur page semble plus agréable.


exemple de fichier 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. 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>

Jun XSD file

<?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>
26
répondu parvus 2017-05-23 12:03:02

Je n'ai pu trouver aucune bonne information à ce sujet, donc j'ai fait quelques essais et erreurs. Les attributs et les champs suivants (et seulement ces) sont reconnus par 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>

(j'ai commencé par cet exemple de document XML et j'ai travaillé à l'envers à partir de là.)

23
répondu Ian 2016-06-03 14:30:57

il y a plusieurs schémas pour les résultats" JUnit "et" xUnit".

veuillez noter qu'il existe plusieurs versions du schéma utilisé par le plugin Jenkins xunit (la dernière version actuelle est junit-10.xsd qui ajoute le support pour le format Erlang/OTP Junit).

certains cadres de test ainsi que des plugins de type "xUnit" utilisent aussi leur propre sauce secrète pour générer des rapports de style "xUnit", ceux-ci peuvent ne pas utiliser un schéma particulier (s'il vous plaît lire: ils essaient, mais les outils peuvent ne pas valider contre un schéma particulier). Python unittests in Jenkins? donne une comparaison rapide de plusieurs de ces bibliothèques et de légères différences entre les rapports xml générés.

4
répondu dnozay 2017-05-23 12:18:19

Structure De Base Voici un exemple de fichier de sortie JUnit, montrant un résultat de saut et d'échec, ainsi qu'un seul résultat passé.

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

ci-dessous est la structure documentée d'un rapport XML JUnit typique. Notez qu'un rapport peut contenir une suite de test ou plus. Chaque suite de test possède un ensemble de propriétés (enregistrement des informations sur l'environnement). Chaque suite de test contient 1 ou plusieurs cas de test et chaque scénario de test contiennent un sauté, l'échec ou la noeud d'erreur si le test ne passe pas. Si le cas d'essai a réussi, alors il ne contiendra aucun noeud. Pour plus de détails sur les attributs valides pour chaque noeud, veuillez consulter la section suivante "schéma".

<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>
4
répondu Nayana Adassuriya 2016-05-09 04:13:51

j'ai décidé de poster une nouvelle réponse, parce que certaines réponses sont périmées ou incomplètes.

tout d'abord: il n'y a rien de tel que JUnit XML Format Specification , simplement parce que JUnit ne produit aucun type de rapport XML ou HTML.

la génération de rapports XML elle-même vient de la tâche Ant JUnit/ Maven Surefire Plugin/ Gradle (celui que vous utilisez pour exécuter vos tests). Le format de rapport XML a d'abord été introduit par Ant puis adapté par Maven. (et Gradle).

si quelqu'un a juste besoin d'un format XML officiel alors:

  1. il existe un schéma pour un rapport XML généré par maven surefire et il peut être trouvé ici: surefire-test-report.xsd .
  2. pour un XML généré par ant il y a un schéma de tierce partie disponible ici (mais il pourrait être légèrement dépassé).

j'Espère que ça aidera quelqu'un.

2
répondu G. Demecki 2016-11-24 14:32:03

Bonnes réponses ici sur l'utilisation de python: (il y a beaucoup de façons de le faire) Python unittests in Jenkins?

IMHO le meilleur moyen est write Python unittest tests et install pytest (quelque chose comme "yum install pytest") pour obtenir py.test d'installation. Puis exécuter des tests comme ceci: "py.test -- résultats junitxml.xml test.py " . Vous pouvez exécuter n'importe quel script Python unittest et obtenir jUnit xml résultat.

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

dans jenkins build configuration post-build actions ajouter une action "Publish JUnit test result report" Avec résultat.xml et tous les fichiers de résultats de test que vous produisez.

1
répondu gaoithe 2017-05-23 12:18:19