• 使用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)函数进行转换。

  • 相关阅读:
    php pdo备份还原数据库方法
    php抛出异常
    手机H5支持视频的比特率
    linux 安装imagick方法 php5.4以上都能用
    lnmp一键安装包 成功运行thinkphp的方法
    NAVICAT文件名目录或卷标语法不正确怎么办
    Linux下捕捉键盘事件
    linux 下shell脚本备份文件
    MQTT学习笔记
    windows生成dump文件
  • 原文地址:https://www.cnblogs.com/StitchSun/p/4233904.html
Copyright © 2020-2023  润新知