Junit 如何在哈德逊/詹金斯获得CTest结果

Junit 如何在哈德逊/詹金斯获得CTest结果,junit,hudson,cmake,jenkins,ctest,Junit,Hudson,Cmake,Jenkins,Ctest,我正在使用CTest(CMake的一部分)进行自动化测试 如何在Jenkins仪表板中获得CTest结果?或者,用不同的措辞,如何让CTest以类似JUnit的XML格式输出?在Jenkins中,在CMake部分(可能通过CMake插件制作)之后,添加以下批处理脚本,或者适应Linux上的构建: del build_32\JUnitTestResults.xml pushd build_32\Tests "C:\Program Files\CMake 2.8\bin\ctest.exe" -T

我正在使用CTest(CMake的一部分)进行自动化测试


如何在Jenkins仪表板中获得CTest结果?或者,用不同的措辞,如何让CTest以类似JUnit的XML格式输出?

在Jenkins中,在CMake部分(可能通过CMake插件制作)之后,添加以下批处理脚本,或者适应Linux上的构建:

del build_32\JUnitTestResults.xml
pushd build_32\Tests
"C:\Program Files\CMake 2.8\bin\ctest.exe" -T Test -C RelWithDebInfo --output-on-failure
popd
verify >nul
C:\Python27\python.exe external/tool/CTest2JUnit.py build_32/Tests external/tool/CTest2JUnit.xsl > build_32/JUnitTestResults.xml
  • build_32
    是CMake插件中的构建目录
  • Tests
    是所有测试所在的子目录
  • -T Test
    以XML形式输出CTest(?)
  • verify>nul
    将errorlevel重置为0,因为如果任何测试失败,CTest将返回>0,Jenkins将其解释为“整个构建失败”,这是我们不希望看到的
  • 最后一行将CTest的XML转换为最小的junitxml。Python脚本和xslt位于源目录中,您可能需要对此进行更改
python脚本如下所示(注意,10分钟内就被砍掉了):

  • 它需要lxml
  • 它有两个参数,测试所在的目录(在构建目录中)和一个xsl文件
  • 它只读取最后的xml测试结果,用xsl进行转换,并将其输出到标准输出
  • “最后的xml测试”出现在
    Testing/TAG
    文件的第一行,因此增加了fopen
xsl如下所示。它非常简单,但完成了任务:[编辑]请参阅MOnsDaR的改进版本:


最后,选中“发布JUnit测试结果”(或类似的,我的版本是法语),并将xml路径设置为
build\u 32/junitestresults.xml


那太难看了。但还是希望这能帮助到别人。欢迎改进(可能从python运行ctest?使用python插件的路径而不是C:…?)

这似乎已集成到jenkins ci中:


非常感谢您提供此解决方案。我目前正在使用它,它基本上对我来说非常适合。我增强了XSL代码以支持CTest XML输出的更多功能:它现在增加了测试的执行时间,如果出现错误,它会将errortype和errorcode作为消息添加。如果有其他东西可以添加到生成的JUnit-File中,请发表评论。新版本支持JUnit的-标记,并将属性另外存储为system out(因此可以在Jenkins中看到):在Linux上,您可以使用xsltproc+shell实现相同的结果:将XSL文件复制到某个位置,然后使用以下命令:xsltproc ctest2junix.xsl Testing/
head-n1
/Test.xml>junitestresults.xml
head-n…
命令应包含在反引号中…我进一步改进了@MOnsDaR xslt中的xslt文件:它将testclassname填充为“this/Path”,测试和失败。
from lxml import etree
import StringIO
import sys

TAGfile = open(sys.argv[1]+"/Testing/TAG", 'r')
dirname = TAGfile.readline().strip()

xmlfile = open(sys.argv[1]+"/Testing/"+dirname+"/Test.xml", 'r')
xslfile = open(sys.argv[2], 'r')

xmlcontent = xmlfile.read()
xslcontent = xslfile.read()

xmldoc = etree.parse(StringIO.StringIO(xmlcontent))
xslt_root = etree.XML(xslcontent)
transform = etree.XSLT(xslt_root)

result_tree = transform(xmldoc)
print(result_tree)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

    <xsl:template match="/Site/Testing">    
        <testsuite>
            <xsl:apply-templates select="Test"/>
        </testsuite>
    </xsl:template>

    <xsl:template match="Test">
        <xsl:variable name="testcasename"><xsl:value-of select= "Name"/></xsl:variable>
        <xsl:variable name="testcaseclassname"><xsl:value-of select= "FullName"/></xsl:variable>
        <testcase name="{$testcasename}" classname="{$testcaseclassname}">
            <xsl:if test="@Status = 'passed'">
            </xsl:if>
            <xsl:if test="@Status = 'failed'">
                <error type="error"><xsl:value-of select="Results/Measurement/Value/text()" /></error>
            </xsl:if>
            <xsl:if test="@Status = 'notrun'">
                <skipped><xsl:value-of select="Results/Measurement/Value/text()" /></skipped>
            </xsl:if>
        </testcase>
    </xsl:template>

</xsl:stylesheet>