[jenkins] Hudson이 지원하는 JUnit XML 형식 사양은 무엇입니까?

연속 통합 서버로 Hudson을 사용하고 있으며 ‘Publish JUnit 테스트 결과 보고서’옵션을 사용하고 싶습니다. 그러나 테스트를 위해 xUnit 도구를 사용하지 않습니다. 대신 테스트를 실행하고 간단한 형식으로 결과를 반환하는 쉘 스크립트가 있습니다. 이 결과를 JUnit 형식으로 변환하는 스크립트를 작성하려고합니다. JUnit 파일이 어떻게 보이는지 흥미 롭습니다.



답변

나는 몇 달 전에 비슷한 일을했으며,이 간단한 형식으로 허드슨이 테스트 프로토콜로 받아 들일 수있는 것으로 나타났습니다.

<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 출력용


답변

방금 다른 사람들이 XMLSpear 라는 도구에 링크 하고 스키마를 빈 XML 파일로 변환하기 위해 아래에 표시된 옵션을 사용 하여 junit-4.xsd가져 왔습니다 . 이것은 (약간 정리 된) 결과입니다.

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

이러한 항목 중 일부는 여러 번 나타날 수 있습니다.

  • testsuitesXML이 작동하는 방식이므로 하나의 요소 만있을 수 있지만 testsuite요소 내에 여러 요소 가있을 수 있습니다 testsuites.
  • properties요소는 여러 개의 property하위를 가질 수 있습니다 .
  • testsuite요소는 여러 개의 testcase하위를 가질 수 있습니다 .
  • testcase요소는 여러 가질 수 error, failure, system-out, 또는 system-err아이들.

XMLSpear 옵션


답변

질문 Anders Lindahl최상위 답변xsd 파일을 나타냅니다 .

개인적 으로이 xsd 파일 도 매우 유용하다는 것을 알았습니다 (어떻게 찾았는지 기억하지 못합니다). 조금 덜 위협적으로 보이며 사용했던 한 모든 요소와 속성이 Jenkins (v1.451)에 의해 인식되는 것처럼 보입니다.

그러나 한 가지 : 여러 <failure ...요소를 추가 할 때 Jenkins에는 하나만 유지되었습니다. xml 파일을 만들 때 모든 실패를 하나로 연결합니다.


2016-11 업데이트 링크가 끊어졌습니다. 더 나은 대안은 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. 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 (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 문서로 시작하여 거꾸로 작업했습니다.)


답변

기본 구조 다음은 건너 뛰기 및 실패한 결과와 하나의 전달 된 결과를 표시하는 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 보고서의 문서화 된 구조입니다. 보고서에는 하나 이상의 테스트 스위트가 포함될 수 있습니다. 각 테스트 스위트에는 일련의 속성 (레코딩 환경 정보)이 있습니다. 각 테스트 스위트에는 하나 이상의 테스트 케이스가 포함되어 있으며 테스트에 통과하지 못한 경우 각 테스트 케이스에는 건너 뛰기, 실패 또는 오류 노드가 포함됩니다. 테스트 사례가 통과 한 경우 노드가 포함되지 않습니다. 각 노드에 유효한 속성에 대한 자세한 내용은 다음 “스키마”섹션을 참조하십시오.

<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”결과에 대한 여러 스키마가 있습니다.

Jenkins xunit-plugin에서 사용중인 여러 버전의 스키마가 있습니다 (현재 최신 버전은 junit-10.xsdErlang / OTP Junit 형식에 대한 지원을 추가 함).

“xUnit”스타일보고 플러그인뿐만 아니라 일부 테스트 프레임 워크는 고유 한 비밀 소스를 사용하여 “xUnit”스타일 보고서를 생성합니다. 이러한 스키마는 특정 스키마를 사용하지 않을 수 있습니다 (읽어보십시오. 그러나 도구는 검증되지 않습니다) 하나의 스키마). 젠킨스에서 파이썬 단위 테스트? 이러한 라이브러리 중 몇 가지를 빠르게 비교하고 생성 된 xml 보고서간에 약간의 차이가 있습니다.


답변

파이썬 사용에 대한 좋은 대답 : 젠킨스에서 파이썬 단위 테스트 는 (여러 가지 방법이 있습니다)
?

가장 좋은 방법은 파이썬 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 및 더 많은 테스트 결과 파일이 포함 된 “Publish JUnit 테스트 결과 보고서”조치를 추가하십시오.