HudsonがサポートするJUnit XML形式の仕様は何ですか?


183

Hudsonを継続的インテグレーションサーバーとして使用しており、「JUnitテスト結果レポートを公開」オプションを使用したい。しかし、私はテストにxUnitツールを使用していません。代わりに、テストを実行して結果を単純な形式で返すシェルスクリプトを使用しています。これらの結果をJUnit形式に変換するスクリプトを作成することを考えています。それで、JUnitファイルがどのように見える必要があるのか​​興味がありますか?


JUnitを使用しない理由は何ですか?これらのテストは...など、UIをcmdをさまざまなツールを経由して様々な方法で自動化することができます
アーロンMcIver

6
@AaronMcIver:シェルスクリプトは(Java以外の言語で)テストを実行するのに非常に適しています。そのためにJUnitをどのように使用しますか?
Ben Voigt

1
@BenVoigt私は当初、OPにJavaが含まれていると想定し、テストハーネスとしてJUnitをバイパスすることを検討していました。これは、質問を確認した後では、ほとんどの場合当てはまりません。と思われるcode.google.com/p/shell2junitが二見た目後OPにいくつかの使用を提供することができます。
アーロン・マクバー

1
ここにshell2unitの行に沿って、JUnit XMLを解析/出力できる私が作成したJAXBクラスがあります:gist.github.com/agentgt/8583649
Adam Gent

回答:


127

私は数か月前に同様のことをしましたが、この単純な形式はHudsonがテストプロトコルとして受け入れるのに十分であることがわかりました。

<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出力の場合


xunitプラグインは 'classname'属性を拒否し、 'class'のみを受け入れるため、この回答を修正してください
andho

10
私は反対の問題を抱えていました。class拒否され、classname機能しました。
ライアンブレナード

1
xUnitプラグインを1.60にアップグレードすると、失敗し始めました。バリデーターがより厳しくなり、<testsuite tests="(number of tests)">ex を追加する必要があることがわかりました。<testsuite tests="10">
Kevin Brotcke 2013年

2
@KevinBrotckeに感謝します。その属性を含めるように回答を更新します。
Anders Lindahl 2013年

2
また、Hudsonでパッケージ/スイートごとにテストを整理するには、classname属性でパッケージを指定する必要があります。例:<testcase classname="foo.bar" name="ATest" /> これにより、Jenkinsのfooパッケージにbarクラスが配置され、テストコレクションがより整理されます。
jluzwick 2013

90

私はちょうどつかん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が機能するため、要素は1つしか存在できませんが、testsuite要素内には複数の要素を含めることができますtestsuites
  • properties要素は複数のproperty子を持つことができます。
  • testsuite要素は複数のtestcase子を持つことができます。
  • testcase要素は複数持つことができerrorfailuresystem-out、またはsystem-err子供を。

XMLSpearオプション


1
テストケースのステータスやエラーのタイプなど、特定の属性の有効な値を説明するドキュメントはありますか?
Eric Cope、

1
@EricCopeソースコードsvn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/…を見ることをお勧めします。基本的には文字列です。
サルタン

4
タグが複製されるのはなぜですか?
ナキロン2014

設定ミラー:imgur.com/quneFJf ALT: :RootelementtestsuitesMax recursive de...2Max Repeat factor2:(include optional elementsはい=ティック)、(include optional attributesはい=チェックが入っ)
n611x007

1
@Nakilon 2.5年遅れですが、修正しました
bdesham

45

Anders Lindahlは、xsdファイルを参照しているという質問のトップアンサーです

個人的には、このxsdファイルも非常に便利であることがわかりました(どのようにして見つけたのか覚えていません)。それは少し威圧的に見えません、そして私がそれを使用した限りでは、すべての要素と属性はジェンキンス(v1.451)によって認識されているようです

ただし、複数の<failure ...要素を追加すると、1つだけがJenkinsに保持されていました。xmlファイルを作成するときに、すべての失敗を1つに連結します。


アップデート2016-11現在、リンクは壊れています。より良い代替手段は、cubic.orgのこのページです。JUnitXML レポートファイル形式。ここでは、文書化された賢明な例を提供するために努力が払われています。例と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. 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ファイル

<?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に表示されません。
rationalcoder

それは私のアプローチの欠点です。井戸で苦労したことを覚えています。&lt; br /&gt;のようなものを追加してみてください -私はこれがどのように解決されたかを忘れました(そして私たちはこれをもう使用していません)が、これは試す価値のあるもののようです。
parvus

1
私はそれを回避する方法を見つけました。私たちはc ++を使用しているため、失敗メッセージで失敗の数を報告し、実際の失敗を報告するために「スタックトレース」を使用しています。スタックトレースは、failure要素の本文を含むテキストから報告されるため、新しい行が正しくサポートされます。
rationalcoder

25

これに関する良い情報が見つからなかったので、試行錯誤を繰り返しました。次の属性とフィールド(およびこれらのみ)は、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文書から始めて、そこから逆に作業しました。)


6

基本的な構造これは、スキップされた結果と失敗した結果、および単一の渡された結果を示す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レポートの文書化された構造です。レポートには1つ以上のテストスイートを含めることができます。各テストスイートには、一連のプロパティ(環境情報の記録)があります。各テストスイートには1つ以上のテストケースも含まれ、テストに合格しなかった場合、各テストケースには、スキップされた、失敗した、またはエラーのノードが含まれます。テストケースに合格した場合、ノードは含まれません。各ノードで有効な属性の詳細については、次のセクション「スキーマ」を参照してください。

<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

「JUnit」と「xUnit」の結果には、複数のスキーマがあります。

Jenkins xunit-pluginで使用されているスキーマのバージョンがいくつかあることに注意してください(現在の最新バージョンはjunit-10.xsd、Erlang / OTP Junit形式のサポートを追加しています)。

一部のテストフレームワークと「xUnit」スタイルのレポートプラグインは、独自のシークレットソースを使用して「xUnit」スタイルのレポートを生成します。これらは特定のスキーマを使用しない場合があります(お読みください。 1つのスキーマ)。ジェンキンスでのPythonユニットテスト?これらのライブラリのいくつかをすばやく比較し、生成されたxmlレポート間のわずかな違いを示します。


2

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ビルド構成では、ビルド後のアクション「JUnitテスト結果レポートの発行」アクションを、result.xmlおよび作成したテスト結果ファイルとともに追加します。


2

既存の回答の一部が古くなっているか不完全であるため、新しい回答を投稿することにしました。

まず第一に、JUnit XML Format SpecificationJUnitがどのような種類のXMLまたはHTMLレポートも生成しないため、のようなものはありません。

XMLレポートの生成自体は、Ant JUnitタスク/ Maven Surefireプラグイン/ Gradle(テストの実行に使用する方)から行われます。XMLレポート形式は、最初にAntによって導入され、後にMaven(およびGradle)によって適応されました。

誰かが公式のXML形式だけを必要とする場合:

  1. maven確実に生成されたXMLレポートのスキーマが存在し、それはここにあります:surefire-test-report.xsd
  2. antで生成されたXMLの場合、サードパーティのスキーマがここにあります(ただし、少し古くなっている可能性があります)。

それが誰かを助けることを願っています。


ご説明ありがとうございます。古いJenkins 1.6インスタンスからSlackにJUnitテストの概要送信しようとしています。そのようなXMLファイルはどこに配置しますか?
JJD 2017

@JJD申し訳ありません、私はあなたを理解していません。そのようなXMLファイルとは正確にはどういう意味ですか?しかし、私はすでにant / maven / gradleでJUnitテストを実行していると思いますか?はいの場合、これらのツールは、テストの実行後に、素晴らしい要約レポートを生成します。Jenkinsのバージョンはここでは関係ありません。
G.デメッキ

はい、ビルドはGradle経由で実行されます。Jenkins 1.6を使用しているときに、JUnitテストの概要をSlackチャネルに送信したいと思います。GitHubのディスカッションを読んで、Slackプラグインがテストの概要を取得できるように、構成XMLファイルをどこかに配置する必要があると思いました。多分私は誤解しています。
JJD 2017年

1
GradleがJUnitテストの起動を完了した後、正しく生成されたテストレポートが存在することを確認してください。その後、Slackプラグインはこれらのレポートを使用できるはずです。
G.デメッキ

1
最後に、あなたの助言が正しい方向に私を押しました:XMLファイルを探すために正しいパスを構成する必要がありました複数のGradle製品フレーバーを含む私のAndroidプロジェクトの場合、次のように機能します。どうもありがとうございました!!!**/build/test-results/**/TEST-*.xml
JJD 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.