7

我有一些C++項目運行通過cruisecontrol.net。作爲構建過程的一部分,我們編譯並運行Boost.Test單元測試套件。我將這些配置爲轉儲XML日誌文件。雖然格式與JUnit/NUnit類似,但它不完全相同(並且缺少一些信息),因此cruisecontrol.net無法將其提取出來。我想知道是否有人創建(或知道)將把Boost.Test結果轉換爲JUnit/NUnit格式或者直接轉換爲呈現(html)格式的現有XSL轉換。任何人都有一個XSL將Boost.Test XML日誌轉換爲可表現的格式?

謝謝!

+0

JUnit是因爲升壓1.62的原生支持的格式boost.test – Raffi 2017-04-20 17:39:42

回答

5

我正在滾動我自己的Boost.Test - > JUnit XSL。請注意,這是爲了消耗Boost.Test輸出的XML 報告 - 而不是輸出日誌。這是一項正在進行的工作 - 這是我到目前爲止有:

<?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數據映射到JUnit報告的「全部」,「失敗」,「跳過」和「未運行」字段,我很樂於提供建議。此外,不幸的是,錯誤詳細數據(表明失敗的性質和發生故障的文件/行號)僅打印到日誌中,而不是打印到報告中,因此我必須「合併」兩者以獲取所有我想理想的數據。

1

我們用--report_format=xml --report_level=detailed --log_level=test_suite --log_format=xml運行我們的測試。你既需要stderr和標準輸出,那麼我們更換<TESTLOG>與<XML> <TESTLOG>與</TestResult中> <XML>更換</TestResult中>。之後,我們雖然整潔地運行它,並最終運行,儘管這個xslt。

您還必須小心,在stdout/err中不要有任何xml樣式的標籤。像<foo>可以打破轉換。

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

5

感謝司徒蘭格的回答上面,我是能夠得到如Boost.Test的輸出與我們的竹構建系統集成。竹描述格式,他們可以攝取這裏:

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離開印刷機,但它足以看出套房外,測試包含,以及哪些(如果有的話)失敗。

另外還有一點需要注意,用這種方法只需要捕獲stderr輸出。標準輸出的內容(至少是我們使用Boost.Test的方式)會破壞事物。

+0

我需要你登錄你的其他賬戶,並給它一個電子郵件地址(與該賬戶相同),然後才能合併。 – Will 2011-01-24 19:23:25

+0

如何轉換XML?直接在竹子?如果是的話,你是怎麼做到的? – Mike 2013-03-07 16:20:14

+0

我們將XSL轉換作爲螞蟻任務的一部分。但是,無論您構建的工作流程是什麼,都有很多方法可以實現。 – joeymink 2014-01-13 21:22:41

0

有趣的是沒有的上面爲我工作,也許是因爲新的CruiseControl(2.8.4),但無論如何。 CruiseControl會忽略上面所轉換的所有「錯誤」和「失敗」屬性,並且它會自行查詢子元素。現在這實際上顯示了有多少測試成功了,哪些失敗了。

將來自boost測試日誌文件的更具體的失敗信息摺疊(但也許其他人可以從這裏獲取)將是很好的。

關鍵點:指定以下標誌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&gt; @{file}.log.xml 2&gt; @{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>