연속 통합 서버로 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아이들.
답변
질문 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”결과에 대한 여러 스키마가 있습니다.
- 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에서 사용중인 여러 버전의 스키마가 있습니다 (현재 최신 버전은 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 테스트 결과 보고서”조치를 추가하십시오.

