У меня есть Hudson в качестве сервера непрерывной интеграции, и я хочу использовать опцию «Опубликовать отчет о результатах тестирования JUnit». Но я не использую инструменты xUnit для тестирования, вместо этого у меня есть сценарии оболочки, которые запускают тесты и возвращают результаты в простом формате. Думаю создать сценарий, который преобразует эти результаты в формат JUnit. Итак, мне интересно, как должен выглядеть файл JUnit?
Какую спецификацию формата JUnit XML поддерживает Hudson?
Ответы (8)
Я сделал то же самое несколько месяцев назад, и оказалось, что этого простого формата было достаточно, чтобы Хадсон принял его в качестве протокола тестирования:
<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>
На этот вопрос есть ответы с более подробной информацией: Spec. для вывода XML JUnit
class
был отклонен, и только classname
сработало.
- person ryanbrainard; 09.02.2012
<testsuite tests="(number of tests)">
ex. <testsuite tests="10">
.
- person Kevin Brotcke; 07.06.2013
<testcase classname="foo.bar" name="ATest" />
Это поместит класс bar в пакет foo на Jenkins, что сделает вашу тестовую коллекцию более организованной.
- person jluzwick; 11.09.2013
STDOUT
и STDERR
в результаты.
- person Ian; 16.12.2019
Я только что взял 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, но внутриtestsuites
элемента может быть несколькоtestsuite
элементов. - У каждого
properties
элемента может быть несколькоproperty
дочерних элементов. - У каждого
testsuite
элемента может быть несколькоtestcase
дочерних элементов. - У каждого
testcase
элемента может быть несколькоerror
,failure
,system-out
илиsystem-err
дочерних элементов.
Rootelement
: testsuites
, Max recursive de...
: 2
, Max Repeat factor
: 2
, include optional elements
: (да = отмечен), include optional attributes
: (да = отмечен)
- person n611x007; 22.04.2015
главный ответ на вопрос Андерс Линдал ссылается на файл xsd.
Лично я нашел этот файл xsd тоже очень полезен (не помню, как я его нашел). Это выглядит немного менее устрашающе, и насколько я его использовал, все элементы и атрибуты, похоже, распознаются Jenkins (v1.451)
Одно но: при добавлении нескольких элементов <failure ...
в Jenkins остался только один. При создании файла xml я теперь объединяю все сбои в один.
Обновление 2016-11 гг. Сейчас ссылка не работает. Лучшей альтернативой является эта страница с сайта cubic.org: формат файла отчетов JUnit XML, где приятно были предприняты усилия, чтобы предоставить разумный задокументированный пример. Пример и xsd скопированы ниже, но их страница выглядит лучше.
образец 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>
Файл XSD JUnit
<?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. Обратите внимание, что отчет может содержать 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>
Я решил опубликовать новый ответ, потому что некоторые существующие ответы устарели или неполны.
Прежде всего: нет ничего лучше JUnit XML Format Specification
просто потому, что JUnit не создает никаких отчетов в формате XML или HTML.
Само создание XML-отчета происходит из Ant JUnit task / Maven Surefire Plugin / Gradle (в зависимости от того, что вы используете для запуска ваших тестов). Формат отчета XML был впервые представлен Ant, а затем адаптирован Maven (и Gradle).
Если кому-то нужен только официальный формат XML, то:
- Существует схема для XML-отчета, созданного maven surefire, и ее можно найти здесь: surefire-test-report.xsd.
- Для сгенерированного муравьями XML есть сторонняя схема, доступная здесь (но, возможно, он немного устарел).
Надеюсь, это кому-нибудь поможет.
**/build/test-results/**/TEST-*.xml
. Большое тебе спасибо!!!
- person JJD; 09.05.2017
Существует несколько схем для результатов "JUnit" и "xUnit".
- XSD для вывода JUnit Apache Ant можно найти по адресу: https://github.com/windyroad/JUnit-Schema (кредит принадлежит этому ответу: https://stackoverflow.com/a/4926073/1733117)
- XSD от Jenkins xunit-plugin можно найти по адресу: https://github.com/jenkinsci/xunit-plugin/tree/master/src/main/resources/org/jenkinsci/plugins/xunit/types (под
model/xsd
)
Обратите внимание, что есть несколько версий схемы, используемых плагином Jenkins xunit-plugin (текущая последняя версия - junit-10.xsd
, которая добавляет поддержку формата Erlang / OTP Junit).
Некоторые платформы тестирования, а также плагины для создания отчетов в стиле «xUnit» также используют свой секретный соус для создания отчетов в стиле «xUnit», которые могут не использовать определенную схему (пожалуйста, прочтите: они пытаются, но инструменты могут не проверять на соответствие каким-либо одна схема). Модульные тесты Python в Jenkins? дает быстрое сравнение нескольких из этих библиотек и небольшие различия между XML отчеты созданы.
Хорошие ответы об использовании python: (есть много способов сделать это) Модульные тесты Python в Jenkins?
ИМХО, лучший способ - это написать тесты python unittest и установить pytest (что-то вроде 'yum install pytest'), чтобы установить py.test. Затем запустите такие тесты: 'py.test --junitxml results.xml test.py'. Вы можете запустить любой скрипт python unittest и получить результаты jUnit xml.
https://docs.python.org/2.7/library/unittest.html
В конфигурации сборки jenkins Действия после сборки Добавьте действие «Опубликовать отчет о результатах теста JUnit» с помощью result.xml и других файлов результатов тестирования, которые вы создаете.