思路:css
1.使用xslt樣式,這樣能夠很好的和xml結合,作出漂亮的報告html
2.生成xml結構node
xslt樣式是個頗有意思,也很強大的,如今用的不少,很方便就能作出一個漂亮的報告,能夠百度一下,語法至關簡單,跟寫html差很少的.python
在這裏能夠定製好,咱們要生成報告,是什麼樣子的,而後在從xml獲取數據.app
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <Head> <style type="text/css"> body { background:#fff; margin:0; padding:40px 20px; font-family: "Arial", Arial, Sans-serif; font-size: 16px; color:#000; } table { margin:5px 5px 0; border:0px solid #222; font-size: 0.8em; } td { margin:5px 5px 0; padding:10px 10px 10px 10px; vertical-align:text-top; border:1px solid #222; border-width:1px 1px 1px 1px; } td.light { border:0px solid #222; } td.number { text-align:right; } td.status { text-align:right; vertical-align:text-bottom; } </style> </Head> <body> <!--OVER RESULT --> <xsl:variable name="OVER_STATUS" select="REPORT/OVER_STATUS"/> <xsl:variable name="STATUS" select="REPORT/LOG_ENTRY/STATUS"/> <h2>自動化測試執行報告</h2> <!--table --> <table border="1"> <!--all result value--> <tr bgcolor="white" height = "35"> <td>Overall Test Result</td> <td><xsl:value-of select="$OVER_STATUS"/></td> <td colspan="2"> </td> </tr> <tr bgcolor="#D8BFD8" height = "35"> <th>執行時間</th> <th>單步結果</th> <th>響應CODE</th> <th>Response信息</th> </tr> <!--select font color --> <xsl:variable name="fontColor"> <xsl:choose> <xsl:when test="$STATUS = FAILED or $STATUS = PASSED"> <xsl:text>white</xsl:text> </xsl:when> <xsl:otherwise>black</xsl:otherwise> </xsl:choose> </xsl:variable> <!--background color--> <xsl:variable name="backgroundColor"> <xsl:choose> <xsl:when test="$STATUS = 'FAILED'"> <xsl:text>rgb(255,0,0)</xsl:text> </xsl:when> <xsl:when test="$STATUS = 'PASSED'"> <xsl:text>rgb(60,179,113)</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>white</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:variable> <!--log entry--> <xsl:for-each select = "REPORT/LOG_ENTRY"> <tr> <td><xsl:value-of select="EXECUTION_TIME"/></td> <td bgcolor="{$backgroundColor}"><xsl:value-of select="STEP_RESULT"/></td> <td><xsl:value-of select="COMPONENT_NAME"/></td> <td><xsl:value-of select="STEP_DESCRIPTION"/></td> </tr> </xsl:for-each> <tr bgcolor="white"> <font color="{$fontColor}"> <td colspan="4">Overall Test Result:<xsl:value-of select="$OVER_STATUS"/></td> </font> </tr> </table> </body> </html> </xsl:template> </xsl:stylesheet>
xml是要按照,xslt定製的結構進行生成,或者換句話說,xslt樣式要按照xml結構去作dom
xml結構函數
REPORT/LOG_ENTRY測試
REPORT下OVER_STATUS節點,這個是整個報告的結果,只有當全部條目爲passed時纔會爲passedspa
每一個LOG_ENTRY節點,表明一行數據3d
包括:
STATUS單行數據執行狀態
EXECUTION_TIME執行時間
STEP_RESULT單步執行結果
COMPONENT_NAME組件名稱,
STEP_DESCRIPTION步驟描述
固然這些均可以自已定義,能夠本身增長或減小,可是xslt表中也要相對應的增長或減小
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet href="LOG.XSLT" type="text/xsl"?> <REPORT> <OVER_STATUS>PASSED</OVER_STATUS> <LOG_ENTRY> <STATUS>FAILED</STATUS> <EXECUTION_TIME>2017.06.15 15:57:16</EXECUTION_TIME> <STEP_RESULT>FAILED</STEP_RESULT> <COMPONENT_NAME>704</COMPONENT_NAME> <STEP_DESCRIPTION>{u'nextUrl': u'http://www.elong.com', u'message': u'\u9a8c\u8bc1\u7801\u9519\u8bef', u'code': u'704', u'success': False, u'isShowVerifyCode': True}</STEP_DESCRIPTION> </LOG_ENTRY> <LOG_ENTRY> <STATUS>FAILED</STATUS> <EXECUTION_TIME>2017.06.15 15:57:16</EXECUTION_TIME> <STEP_RESULT>FAILED</STEP_RESULT> <COMPONENT_NAME>704</COMPONENT_NAME> <STEP_DESCRIPTION>{u'nextUrl': u'http://www.elong.com', u'message': u'\u9a8c\u8bc1\u7801\u9519\u8bef', u'code': u'704', u'success': False, u'isShowVerifyCode': True}</STEP_DESCRIPTION> </LOG_ENTRY> </REPORT>
下面上,生成xml的python代碼,這個建立xml結構就很簡單了.
使用xml.dom.minidom就能夠了,掌握幾個要點很容易就建立一個xml
1,建立一個xml文檔
import xml.dom.minidom as xmlDoc #xmlDoc起的別名 xmldoc = xmlDoc.Document
2.由於咱們要使用xslt樣式,因此呢.
建立的xml第一行是xml頭 <?xml version="1.0" encoding="utf-8"?> 這樣python默認已經有了,就不用咱們建立了,那麼
第二行,咱們要寫樣式頭 <?xml-stylesheet href="LOG.XSLT" type="text/xsl"?> 頭中寫了引用相同目錄下的LOG.XSLT ,類型TEXT/XSL
要注意一點href屬性不要寫成這樣D:\demo\LOG.XSLT 這樣寫會有問題,只要把這個文件和xml放在同一目錄就行了.
#xml樣式 xlstNode = xmlD.createProcessingInstruction("xml-stylesheet","href=\"LOG.XSLT\" type=\"text/xsl\"") xmlD.appendChild(xlstNode)
3.建立一個REPORT根節點,你也能夠起名ROOT,叫什麼名字看你本身了
建立節點用,createElement,以後用appendChild增長節點到xml對象
report = xmlD.createElement('REPORT') xmlD.appendChild(report)
4.以後建立其它節點,同樣用createElement,可是若是節點下要增長內容要用xmlDoc.createTextNode('passed')
如下代碼意思是:建立一個over_status的節點,節點文本爲passed,而後,將此節點增長到根節點REPORT下
overStatus = xmlD.createElement('OVER_STATUS') overStatus.appendChild(xmlD.createTextNode('PASSED')) report.appendChild(overStatus)
有以上4點,基本建立一個xml沒有問題了.
生成xml具體python代碼:
如下代碼建立根節點作爲了一個單獨的函數,之因此這麼作由於要生成的報告,只建立一個根節點,和over_status 結果狀態
其它累加的行放在了節點LOG_ENTRY下,一個根節點下能夠有多個LOG_ENTRY節點........一個LOG_ENTRY節點代碼一行數據執行結果
#*_*coding:utf-8*_* import xml.dom.minidom as xmlDoc import os import gl import sys class cREPORTXML(object): def __init__(self): self.__struct = self.createReportNode() #建立report節點 def createReportNode(self): try: xmlD = xmlDoc.Document() #xml樣式 xlstNode = xmlD.createProcessingInstruction("xml-stylesheet","href=\"LOG.XSLT\" type=\"text/xsl\"") xmlD.appendChild(xlstNode) report = xmlD.createElement('REPORT') xmlD.appendChild(report) overStatus = xmlD.createElement('OVER_STATUS') overStatus.appendChild(xmlD.createTextNode('PASSED')) report.appendChild(overStatus) returnResult = [] returnResult.append(xmlD) returnResult.append(report) except Exception,ex: return ex.message return returnResult def writeReport(self,execTime,stepResult,comName,stepDisc): #reportNodeList = self.createReportNode() entry = self.createLogEntry(self.__struct[0],execTime,stepResult,comName,stepDisc) self.__struct[1].appendChild(entry) self.writeXml(self.__struct[0],gl.reporterPath+'reportxml.xml') #self.writeXml(self.__struct[0],gl.reporterPath+'reportxml_%s.xml'%(gl.curTimeStr)) #-------------建立xml格式-有多個相同的節點,而且該節點下有4個名稱相同的子節點---------------- def createLogEntry(self,docObj,executeTime,stepResult,componentName,stepDiscription): entry = docObj.createElement("LOG_ENTRY") status = docObj.createElement("STATUS") nodeExecuteTime = docObj.createElement("EXECUTION_TIME") nodeStepResult = docObj.createElement("STEP_RESULT") nodeComponentName = docObj.createElement("COMPONENT_NAME") nodeStepDiscription = docObj.createElement("STEP_DESCRIPTION") status.appendChild(docObj.createTextNode(stepResult)) nodeExecuteTime.appendChild(docObj.createTextNode(executeTime)) nodeStepResult.appendChild(docObj.createTextNode(stepResult)) nodeComponentName.appendChild(docObj.createTextNode(componentName)) nodeStepDiscription.appendChild(docObj.createTextNode(stepDiscription)) entry.appendChild(status) entry.appendChild(nodeExecuteTime) entry.appendChild(nodeStepResult) entry.appendChild(nodeComponentName) entry.appendChild(nodeStepDiscription) return entry #參數,xml對象,準備存儲xml文件路徑,文件模式:讀 and 寫 (r and w) def writeXml(self,xmlDoc,xmlPath): f = open(xmlPath,"w") xmlDoc.writexml(f,indent='\t', addindent='\t', newl='\n', encoding="utf-8") #中間的加了一些格式符,這樣生成的xml自動對齊格式 f.close() if __name__=='__main__': reportx =cREPORTXML() print reportx.writeReport('20170602','PASSED','1-SETTEXT','AUTOMATION TEST') print reportx.writeReport('20170606','FIELD','2-SETTEXT','AUTOMATION TEST')
用ie打開xml報告,固然能夠看出總結果顯示有點問題,這個不影響報告展現,代碼中處理一下就好.
簡單的報告就完成了,追求完美的能夠在細化一下,增長一些其它信息,調整一下顏色.