У кого-нибудь есть XSL для преобразования XML-файлов Boost.Test в презентабельный формат?
У меня есть несколько C++ проектов, работающих через cruisecontrol.net. В рамках процесса сборки мы компилируем и запускаем наборы тестов модулей Boost.Test. У меня есть эти настроены для дампа файлов журнала XML. Несмотря на то, что формат похож на JUnit/NUnit, он не совсем тот же (и не хватает некоторой информации), поэтому cruisecontrol.net не может их найти. Мне интересно, если кто-то создал (или знает) существующее XSL-преобразование, которое преобразует результаты Boost.Test в формат JUnit / NUnit или, альтернативно, непосредственно в презентабельный (html) формат.
Спасибо!
5 ответов
Я работаю над созданием собственного Boost.Test -> JUnit XSL. Обратите внимание, что это предназначено для использования вывода отчета XML из Boost.Test, а не вывода журнала. Это работа в процессе - вот что у меня есть до сих пор:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="xml"
indent="yes"/>
<xsl:template match="TestResult">
<test-results>
<xsl:attribute name="total">
<xsl:value-of select="sum(./TestSuite/@test_cases_passed) + sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_skipped) + sum(./TestSuite/@test_cases_aborted)"/>
</xsl:attribute>
<xsl:attribute name="failures">
<xsl:value-of select="sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_aborted)"/>
</xsl:attribute>
<xsl:attribute name="skipped">
<xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
</xsl:attribute>
<xsl:attribute name="not-run">
<xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
</xsl:attribute>
<xsl:call-template name="testSuite" />
</test-results>
</xsl:template>
<xsl:template name="testSuite">
<xsl:for-each select="TestSuite">
<test-suite>
<xsl:call-template name="testAttributes" />
<results>
<xsl:call-template name="testSuite" />
<xsl:for-each select="TestCase">
<test-case>
<xsl:call-template name="testAttributes" />
</test-case>
</xsl:for-each>
</results>
</test-suite>
</xsl:for-each>
</xsl:template>
<xsl:template name="testAttributes">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="success">
<xsl:choose>
<xsl:when test="@result = 'passed'">True</xsl:when>
<xsl:when test="@result != 'passed'">False</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="executed">True</xsl:attribute>
<xsl:attribute name="time">0</xsl:attribute>
<xsl:attribute name="asserts">
<xsl:value-of select="@assertions_failed + @assertions_passed"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Я интегрировал это в свой процесс сборки, и ccnet прекрасно его обрабатывает и обрабатывает. Он не идеален, но работает лучше, чем полное отсутствие отчетов, которое у меня было раньше. Я открыт для предложений о том, как сопоставить данные Boost.Test с полями "total", "failures", "skipped" и "not-run" отчета JUnit. Кроме того, к сожалению, подробные данные об ошибках (с указанием характера сбоя и номера файла / строки, где произошел сбой) печатаются только в журнал, а не в отчет, поэтому мне пришлось бы "объединить" эти два, чтобы получить все данные, которые я в идеале хотел бы иметь.
Благодаря ответу Стюарта Ланге выше, я смог получить выход Boost.Test для интеграции с нашей системой сборки Bamboo. Бамбук описывает формат, который они могут здесь принять:
http://confluence.atlassian.com/display/BAMBOO/JUnit+parsing+in+Bamboo
Таким образом, я использовал XSL Стюарта Ланге выше в качестве отправной точки и в итоге получил следующее:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="xml"
indent="yes"/>
<xsl:template match="TestResult">
<xsl:call-template name="testSuite" />
</xsl:template>
<xsl:template name="testSuite">
<xsl:for-each select="TestSuite">
<testsuite>
<xsl:attribute name="errors">
<xsl:value-of select="@test_cases_failed + @test_cases_aborted"/>
</xsl:attribute>
<xsl:attribute name="tests">
<xsl:value-of select="@test_cases_passed + @test_cases_failed + @test_cases_skipped + @test_cases_aborted"/>
</xsl:attribute>
<xsl:attribute name="skipped">
<xsl:value-of select="@test_cases_skipped"/>
</xsl:attribute>
<xsl:attribute name="failures">
<xsl:value-of select="@test_cases_failed"/>
</xsl:attribute>
<xsl:call-template name="testAttributes" />
<!--results-->
<xsl:call-template name="testSuite" />
<xsl:for-each select="TestCase">
<testcase>
<xsl:call-template name="testAttributes" />
<xsl:call-template name="testCaseElements" />
</testcase>
</xsl:for-each>
<!--/results-->
</testsuite>
</xsl:for-each>
</xsl:template>
<xsl:template name="testAttributes">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="success">
<xsl:choose>
<xsl:when test="@result = 'passed'">True</xsl:when>
<xsl:when test="@result != 'passed'">False</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="executed">True</xsl:attribute>
<xsl:attribute name="time">0</xsl:attribute>
<xsl:attribute name="asserts">
<xsl:value-of select="@assertions_failed + @assertions_passed"/>
</xsl:attribute>
</xsl:template>
<xsl:template name="testCaseElements">
<xsl:if test="@result != 'passed'">
<failure type="No type reported" message="No message reported"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Мы используем следующие параметры командной строки при вызове нашего исполняемого файла Boost.Test:
--report_format=xml
--report_level=detailed
Это не самый горячий XSL, чтобы оставить прессы, но этого достаточно, чтобы увидеть комплекты, содержащиеся в них тесты и то, какие из них (если таковые имеются) потерпели неудачу из Bamboo.
Еще одно замечание: с помощью этого метода вы хотите захватить только вывод stderr. Содержимое stdout (по крайней мере, как мы используем Boost.Test) сломает вещи.
Этот xsl работает для меня для преобразования log.xml Boost.Test в JUnit xml, читаемый Bamboo, с сообщениями!: https://issues.jenkins-ci.org/secure/attachment/19613/boosttest-1.0-to-junit-1.0.xsl
Это связано здесь: https://issues.jenkins-ci.org/browse/JENKINS-7039
Мы проводим наши тесты с --report_format=xml --report_level=detailed --log_level=test_suite --log_format=xml
, Вам нужны и stderr, и stdout, тогда мы заменим
Вы также должны быть осторожны, чтобы в вашем stdout / err не было тегов в стиле xml. Такие вещи, как
<xsl:for-each select="./TestSuite">
<xsl:variable name="name2" select="@name"/>
<testsuite>
<xsl:attribute name="errors">
<xsl:value-of select="@test_cases_failed" />
</xsl:attribute>
<xsl:attribute name="tests">
<xsl:value-of select="@test_cases_failed + @test_cases_passed + @test_cases_skipped" />
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:for-each select="./TestCase">
<xsl:variable name="name3" select="@name"/>
<testcase>
<xsl:attribute name="name">
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:for-each select="/xml/TestLog/TestSuite[@name=$name1]">
<xsl:for-each select="./TestSuite[@name=$name2]">
<xsl:for-each select="./TestCase[@name=$name3]">
<xsl:for-each select="./TestingTime">
<xsl:attribute name="time">
<xsl:value-of select="./text() div 100000"/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="./Error">
<failure>
<xsl:attribute name="type">AssertionFailedError</xsl:attribute>
<xsl:attribute name="message">
<xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
</xsl:attribute>
<xsl:copy-of select="./text()"/>
</failure>
</xsl:for-each>
<xsl:for-each select="./Exception">
<failure>
<xsl:attribute name="type">AssertionFailedException</xsl:attribute>
<xsl:attribute name="message">
<xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
</xsl:attribute>
<xsl:copy-of select="./text()"/>
</failure>
</xsl:for-each>
<system-out>
<xsl:copy-of select="./text()"/>
</system-out>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</testcase>
</xsl:for-each>
</testsuite>
</xsl:for-each>
</testsuite>
Интересно, что ничего из вышеперечисленного не помогло мне, может быть, из-за более нового CruiseControl (2.8.4), но неважно. CruiseControl игнорирует все атрибуты "errors" и "failures", которые создаются вышеупомянутыми преобразованиями, и выполняет собственные запросы к дочерним элементам. Теперь это показывает, сколько тестов прошло успешно, а какие провалились.
Было бы неплохо добавить более конкретную информацию об ошибках из файла журнала буст-теста (но, может быть, кто-то другой может получить информацию здесь).
Ключевой момент: укажите следующие флаги в Boost.Test для разделения stdout/stderr. Вот снимок из скрипта сборки ant:
<exec executable="cmd " dir="bin/x64/Release">
<arg line="/k @{file} --build_info --report_format=xml --report_level=detailed --log_level=all --log_format=xml 1> @{file}.log.xml 2> @{file}.result.xml"/>
</exec>
Затем преобразуйте это:
<xslt in="@{file}.result.xml" out="@{file}.ccresult.xml" style="transform.xslt" />
Фактический transform.xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/TestResult/TestSuite">
<testsuite>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:for-each select="TestCase">
<testcase>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:if test="@result!='passed'">
<failure>See log file.</failure>
</xsl:if>
</testcase>
</xsl:for-each>
</testsuite>
</xsl:template>
</xsl:stylesheet>