使用Python把Gtest XML測試結果轉換為HTML格式


在最近的測試中,使用gtest測試框架對c語言代碼進行測試,結果以XML文件來保存,但是測試結果的查閱和分析非常不方便。便想着把xml的結果直接轉為HTML文件,方便和Jenkins系統對接顯示。因現在的測試方法是使用Python腳本來控制gtest的測試文件運行的,故選用Python腳本來實現xml轉html的功能。

  • 先看結果:

個人對於html不是很熟悉,只是簡單的了解各個元素。要求只有一個,生成的結果清晰明了,便於查閱即可。

 

  • 環境准備:

安裝libxml2 libxstl模塊

Python 2.7環境

Ubuntu 14.04 驗證下通過。

 

  • 輸出:

執行結果生成同名的html文件。

 

Python代碼如下此段代碼是在網上搜索參考的:

原文地址如下:http://blog.csdn.net/zhaoweikid/article/details/74837

我這里進行了簡單的修改,增加了命令行參數。

#!/usr/bin/python
#coding=utf8

import sys
import libxml2
import libxslt

class compoundXML:
    def __init__(self):
        self._result=None
        self._xsl=None
        self._xml=None
    
    def do(self,xml_file_name,xsl_file_name='gtest.xsl'):
        self._xml = libxml2.parseFile(xml_file_name)
        if self._xml ==None:
            return 0
        styledoc = libxml2.parseFile(xsl_file_name)
        if styledoc == None:
            return 0
        self._xsl = libxslt.parseStylesheetDoc(styledoc)
        if self._xsl == None:
            return 0
        self._result = self._xsl.applyStylesheet(self._xml, None)
    def get_xml_doc(self):
        return self._result

    def get_translated(self):
        return self._result.serialize('UTF-8')

    def save_translated(self, file_name): 
        self._xsl.saveResultToFilename(file_name, self._result, 0) 

    def release(self): 
        ''' 
        this function must be called in the end. 
        ''' 
        self._xsl.freeStylesheet() 
        self._xml.freeDoc() 
        self._result.freeDoc() 
        self._xsl = None 
        self._xml = None 
        self._result = None 

def xml2html(xml_file):
    test=compoundXML()
    test.do(xml_file)
    test.save_translated(xml_file+'.html')
    test.release()

if __name__ =='__main__':
    filename=sys.argv[1];
    test=compoundXML()
    test.do(filename)
    #print test.get_translated()
    test.save_translated(filename+'.html')
    test.release()

 

但是這個原文鏈接講的非常不詳細,只是把Python腳本寫了,沒有放xsl模板,在嘗試的時候嘗試了好久,才明白過來需要一個xsl模板,在使用xsl模板來解析gtest測試結果的過程中,調試了好久,終於有一個讓自己滿意的顯示結果。

Xslt解析xml生成html文件,是按照xsl文件的模板來解析,這些都是教訓哈,摸索了好久。

關鍵是根據gtest的xml文件格式,編寫一個合適的xsl模板。

解析gtest xml的Xsl模板如下:

<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="html" indent="yes"/> 

<xsl:template match="/"> 

<table cellpadding="2" cellspacing="5" border="1px">
<tr>
    <th bgcolor="#808080"><font color="#FFFFFF">Testcase Num</font></th>
    <th bgcolor="#808080"><font color="#FFFFFF">Failure Num</font></th>
</tr>
<tr>
    <td style="font-family: Verdana; font-size: 15px; font-weight: bold;"><xsl:value-of select="testsuites/@tests"/> </td>
    <td style="font-family: Verdana; font-size: 15px; font-weight: bold;"><xsl:value-of select="testsuites/@failures"/> </td>
</tr>
</table>

<table cellpadding="2" cellspacing="5"> 
<tr><td style="font-family: Verdana; font-size: 10px;">

<table align="left" cellpadding="2" cellspacing="0" style="font-family: Verdana; font-size: 10px;"> 
<tr>
<th bgcolor="#808080"><font color="#FFFFFF"><b>TestSuites</b></font></th> 
<th bgcolor="#808080">
<table width="1000px" align="left" cellpadding="1" cellspacing="0" style="font-family: Verdana; font-size: 10px;">
<tr style="font-family: Verdana; font-size: 10px;">
<td  width="15%"><font color="#FFFFFF"><b>Testcase</b></font></td>
<td  width="25%"><font color="#FFFFFF"><b>Result</b></font></td>
<td  width="75%"><font color="#FFFFFF"><b>ErrorInfo</b></font></td>
</tr>
</table>
</th> 
</tr> 
<xsl:for-each select="testsuites/testsuite"> 
<tr>
<td style="border: 1px solid #808080"><xsl:value-of select="@name"/></td> 
<td style="border: 1px solid #808080">
<table width="1000px" align="left" cellpadding="1" cellspacing="0" style="font-family: Verdana; font-size: 10px;">
<xsl:for-each select="testcase">
<tr>
<td style="border: 1px solid #808080" width="15%" rowspan="@tests"><xsl:value-of select="@name"/></td>
<xsl:choose>
    <xsl:when test="failure">
      <td style="border: 1px solid #808080" bgcolor="#ff00ff" width="25%">Failure</td>
      <td style="border: 1px solid #808080" bgcolor="#ff00ff" width="70%"><xsl:value-of select="failure/@message"/></td>
    </xsl:when>
    <xsl:otherwise>
     <td style="border: 1px solid #808080" width="25%">Success</td>
     <td style="border: 1px solid #808080" width="70%"><xsl:value-of select="failure/@message"/></td>
     </xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</td> 
</tr>
</xsl:for-each> 
</table> 
</td> 
</tr> 
</table>

</xsl:template>
</xsl:stylesheet> 

  

Xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="22" failures="3" disabled="0" errors="0" time="73.802" name="AllTests">
  <testsuite name="TEST_CStart" tests="14" failures="0" disabled="0" errors="0" time="35.012">
    <testcase name="Normal_ORAY" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_ORAY" status="run" time="0" classname="TEST_CStart" />
    <testcase name="Normal_NOIP" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_NOIP" status="run" time="0.001" classname="TEST_CStart" />
    <testcase name="Normal_HIVIEW" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_HIVIEW" status="run" time="0" classname="TEST_CStart" />
    <testcase name="Normal_CHANGEIP" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_CHANGEIP" status="run" time="0.001" classname="TEST_CStart" />
    <testcase name="Normal_3322" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_3322" status="run" time="0" classname="TEST_CStart" />
    <testcase name="Normal_Dyndns" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_Dyndns" status="run" time="0" classname="TEST_CStart" />
    <testcase name="Normal_easy" status="run" time="5.001" classname="TEST_CStart" />
    <testcase name="WithInited_easy" status="run" time="0.001" classname="TEST_CStart" />
  </testsuite>
  <testsuite name="TEST_CStop" tests="2" failures="0" disabled="0" errors="0" time="0">
    <testcase name="Normal" status="run" time="0" classname="TEST_CStop" />
    <testcase name="WithoutInited" status="run" time="0" classname="TEST_CStop" />
  </testsuite>
  <testsuite name="TEST_DynipCInit" tests="1" failures="0" disabled="0" errors="0" time="0.001">
    <testcase name="Normal_DYNIP" status="run" time="0" classname="TEST_DynipCInit" />
  </testsuite>
  <testsuite name="TEST_DynipCLogSet" tests="1" failures="0" disabled="0" errors="0" time="0">
    <testcase name="Normal_DYNIP" status="run" time="0" classname="TEST_DynipCLogSet" />
  </testsuite>
  <testsuite name="TEST_DynipCRegist" tests="1" failures="1" disabled="0" errors="0" time="19.998">
    <testcase name="Normal_DYNIP" status="run" time="19.998" classname="TEST_DynipCRegist">
      <failure message="Value of: DynipCRegist(&amp;ptDynipCRInfo,dwDnsAddr)&#x0A;  Actual: 4105&#x0A;Expected: 0x1004&#x0A;Which is: 4100" type=""><![CDATA[../_gtest.c:400
Value of: DynipCRegist(&ptDynipCRInfo,dwDnsAddr)
  Actual: 4105
Expected: 0x1004
Which is: 4100]]></failure>
    </testcase>
  </testsuite>
  <testsuite name="TEST_DynipCRefresh" tests="1" failures="1" disabled="0" errors="0" time="3.795">
    <testcase name="Normal_DYNIP" status="run" time="3.795" classname="TEST_DynipCRefresh">
      <failure message="Value of: DynipCRefresh(&amp;ptDynipCRInfo,dwDnsAddr)&#x0A;  Actual: 4117&#x0A;Expected: 0x1014&#x0A;Which is: 4116" type=""><![CDATA[../_gtest.c:413
Value of: DynipCRefresh(&ptDynipCRInfo,dwDnsAddr)
  Actual: 4117
Expected: 0x1014
Which is: 4116]]></failure>
    </testcase>
  </testsuite>
  <testsuite name="TEST_DynipCDeleteRegist" tests="1" failures="1" disabled="0" errors="0" time="14.994">
    <testcase name="Normal_DYNIP" status="run" time="14.994" classname="TEST_DynipCDeleteRegist">
      <failure message="Value of: DynipCDeleteRegist(htonl(638699), htonl(3372250290UL),inet_addr(&quot;8.8.8.8&quot;))&#x0A;  Actual: 4105&#x0A;Expected: 0x1000&#x0A;Which is: 4096" type=""><![CDATA[../_gtest.c:425
Value of: DynipCDeleteRegist(htonl(638699), htonl(3372250290UL),inet_addr("8.8.8.8"))
  Actual: 4105
Expected: 0x1000
Which is: 4096]]></failure>
    </testcase>
  </testsuite>
  <testsuite name="TEST_CGetVersion" tests="1" failures="0" disabled="0" errors="0" time="0">
    <testcase name="Normal" status="run" time="0" classname="TEST_CGetVersion" />
  </testsuite>
</testsuites>

 

使用方法:

把Python腳本和gtest.xsl模板放在同一個目錄下。

一個是使用命令行:

./xml2html.py gtest_reult.xml

二是作為函數調用:

使用xml2html(xml_file)函數進行轉換。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM