前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 生成html测试报表三步曲

python 生成html测试报表三步曲

作者头像
py3study
发布2020-01-10 16:21:17
1.1K0
发布2020-01-10 16:21:17
举报
文章被收录于专栏:python3python3

最近把测试框架优化了一下,原本生成的报表时txt格式的,现在搞成html格式。主要步骤如下

首先找个html处理工具,这样处理html会简单很多

我网上找了一下发现phy停好用,在这里非常感谢pyh的作者

phy源码如下

# @file: pyh.py # @purpose: a HTML tag generator # @author: Emmanuel Turlay <turlay@cern.ch>

__doc__ = """The pyh.py module is the core of the PyH package. PyH lets you generate HTML tags from within your python code. See http://code.google.com/p/pyh/ for documentation. """ __author__ = "Emmanuel Turlay <turlay@cern.ch>" __version__ = '$Revision: 43 $' __date__ = '$Date$'

from sys import _getframe, stdout, modules, version nOpen={}

nl = '/n' doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">/n' charset = '<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />/n'

tags = ['html', 'body', 'head', 'link', 'meta', 'div', 'p', 'form', 'legend', 'input', 'select', 'span', 'b', 'i', 'option', 'img', 'script', 'table', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'fieldset', 'a', 'title', 'body', 'head', 'title', 'script', 'br', 'table','font']

selfClose = ['input', 'img', 'link', 'br']

class Tag(list): tagname = '' def __init__(self, *arg, **kw): self.attributes = kw if self.tagname : name = self.tagname self.isSeq = False else: name = 'sequence' self.isSeq = True self.id = kw.get('id', name) #self.extend(arg) for a in arg: self.addObj(a)

def __iadd__(self, obj): if isinstance(obj, Tag) and obj.isSeq: for o in obj: self.addObj(o) else: self.addObj(obj) return self def addObj(self, obj): if not isinstance(obj, Tag): obj = str(obj) id=self.setID(obj) setattr(self, id, obj) self.append(obj)

def setID(self, obj): if isinstance(obj, Tag): id = obj.id n = len([t for t in self if isinstance(t, Tag) and t.id.startswith(id)]) else: id = 'content' n = len([t for t in self if not isinstance(t, Tag)]) if n: id = '%s_%03i' % (id, n) if isinstance(obj, Tag): obj.id = id return id

def __add__(self, obj): if self.tagname: return Tag(self, obj) self.addObj(obj) return self

def __lshift__(self, obj): self += obj return obj

def render(self): result = '' if self.tagname: result = '<%s%s%s>' % (self.tagname, self.renderAtt(), self.selfClose()*' /') if not self.selfClose(): for c in self: if isinstance(c, Tag): result += c.render() else: result += c if self.tagname: result += '</%s>' % self.tagname result += '/n' return result

def renderAtt(self): result = '' for n, v in self.attributes.iteritems(): if n != 'txt' and n != 'open': if n == 'cl': n = 'class' result += ' %s="%s"' % (n, v) return result

def selfClose(self): return self.tagname in selfClose def TagFactory(name): class f(Tag): tagname = name f.__name__ = name return f

thisModule = modules[__name__]

for t in tags: setattr(thisModule, t, TagFactory(t))

def ValidW3C(): out = a(img(src='http://www.w3.org/Icons/valid-xhtml10', alt='Valid XHTML 1.0 Strict'), href='http://validator.w3.org/check?uri=referer') return out

class PyH(Tag): tagname = 'html' def __init__(self, name='MyPyHPage'): self += head() self += body() self.attributes = dict(xmlns='http://www.w3.org/1999/xhtml', lang='en') self.head += title(name)

def __iadd__(self, obj): if isinstance(obj, head) or isinstance(obj, body): self.addObj(obj) elif isinstance(obj, meta) or isinstance(obj, link): self.head += obj else: self.body += obj id=self.setID(obj) setattr(self, id, obj) return self

def addJS(self, *arg): for f in arg: self.head += script(type='text/javascript', src=f)

def addCSS(self, *arg): for f in arg: self.head += link(rel='stylesheet', type='text/css', href=f) def printOut(self,file=''): if file: f = open(file, 'w') else: f = stdout f.write(doctype) f.write(self.render()) f.flush() if file: f.close() class TagCounter: _count = {} _lastOpen = [] for t in tags: _count[t] = 0 def __init__(self, name): self._name = name def open(self, tag): if isLegal(tag): self._count[tag] += 1 self._lastOpen += [tag] def close(self, tag): if isLegal(tag) and self._lastOpen[-1] == tag: self._count[tag] -= 1 self._lastOpen.pop() else: print 'Cross tagging is wrong' def isAllowed(self, tag, open): if not open and self.isClosed(tag): print 'TRYING TO CLOSE NON-OPEN TAG: %s' % tag return False return True def isOpen(self, tag): if isLegal(tag): return self._count[tag] def isClosed(self, tag): if isLegal(tag): return not self._count[tag]

def isLegal(tag): if tag in tags: return True else: print 'ILLEGAL TAG: %s' % tag return False 第二步,写和DB交互的代码,通常写报表都需要从数据库或其他数据元获取数据。我的比较简单,源代码如下

#coding=utf-8 import loadmylib import dbunit_mysql from pyh import *

class dbreport: def __init__(self,dbinfo='report',project='aliuid',suitid=None): self.db = dbunit_mysql.DBUnit(dbinfo,project) self.suitid = suitid if self.suitid <= 0: print "suitid must not be none" return # def get_taskresult_records(self): try: suitresult = self.db.read("SELECT * FROM ex_suit e where suitid =%d"%self.suitid) taskid = suitresult[0]['taskid'] taskresult = self.db.read("select * from task where taskid = %d"%int(taskid)) return taskresult[0] except: print "getsuitreport error"

def get_groupresult_records(self): try: groupresult = self.db.read("SELECT * FROM ex_group where suitid =%d"%self.suitid) return groupresult except: print "getgroupreport error" def get_failedcase_records(self): try: sqlstr = "SELECT e.*,f.testgroupname FROM ex_case e left join ex_group f on e.testgroupid = f.testgroupid where f.suitid=%d and e.status =1 order by testcaseid"%self.suitid groupresult = self.db.read(sqlstr) return groupresult except: print "getgroupreport error" def get_totalcase_records(self): try: sqlstr = "SELECT e.*,f.testgroupname FROM ex_case e left join ex_group f on e.testgroupid = f.testgroupid where f.suitid=%d order by testcaseid"%self.suitid groupresult = self.db.read(sqlstr) return groupresult except: print "getgroupreport error"

def getcaseresult(): mytab.attributes[''] = ''; pass

if __name__ == '__main__': dbrp = dbreport(suitid=12) result = dbrp.get_failedcase_records() result1 = dbrp.get_totalcase_records() print len(result) print result print result1 第三步,自然是生成报表的代码了。源代码如下

#coding=utf-8 import loadmylib import dbunit_mysql from pyh import * import dbreport import commonfunc import config

class report: def __init__(self,dbinfo='report',project='aliuid',suitid=None): self.page = PyH('%s test report'%project) self.page << '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' self.dbinfo = dbinfo self.project = project self.drp = dbreport.dbreport(dbinfo,project,suitid)

#设定表格的格式 def tablecss(self,table = None,width='90%'): table.attributes['cellSpacing'] = 1; table.attributes['cellPadding'] = 1; table.attributes['border'] = 1; table.attributes['borderColor'] = '#666666'; table.attributes['width'] = width; #set colum title bgcolor def tr_title_css(self,tr = None): tr.attributes['bgcolor'] = '#CCCC00';

#get summary info def gentask_html(self): #get taskresult from mysqldb taskresult = self.drp.get_taskresult_records() sum_div = div(b('.摘要'), id='myCSSid1') self.page << sum_div interfaces = taskresult['modules'] num_interface = len(interfaces.split(',')) totalcase = int(taskresult['totalcase']) failedcase = int(taskresult['failedcase']) successcase = totalcase - failedcase tab_task = self.page << table() self.tablecss(tab_task) title_tr_task = tab_task << tr() self.tr_title_css(title_tr_task) #add task column title title_tr_task << td('测试模块数') title_tr_task << td('通过用例数') title_tr_task << td('失败用例数') title_tr_task << td('总共用例数') #add column value value_tr_task = tab_task << tr() value_tr_task << td('%d'%num_interface) value_tr_task << td('%d'%successcase) value_tr_task << td('%d'%failedcase) value_tr_task << td('%d'%totalcase) self.page.printOut('test.html') self.page << br()

def gengroupreport(self): testgroups = self.drp.get_groupresult_records() sum_div = div(b('.模块测试报告'), id='mydiv2') self.page << sum_div tab_group = self.page << table() self.tablecss(tab_group) title_tr_group = tab_group << tr() self.tr_title_css(title_tr_group) #add task column title title_tr_group << td('模块名称') title_tr_group << td('测试结果') title_tr_group << td('通过用例数') title_tr_group << td('失败用例数') title_tr_group << td('总共用例数') for i in range(len(testgroups)): testgroup = testgroups[i] groupname = testgroup['testgroupname'] groupstatus = int(testgroup['status']) totalcase = int(testgroup['totalcase']) failedcase = int(testgroup['failedcase']) successcase = totalcase - failedcase #add column value value_tr_group = tab_group << tr() value_tr_group << td('%s'%groupname) if groupstatus == 0: value_tr_group << td('Pass') else: value_tr_group << td('Failed') value_tr_group << td('%d'%successcase) value_tr_group << td('%d'%failedcase) value_tr_group << td('%d'%totalcase) self.page << br() def gen_failedcase_report(self): failedcases = self.drp.get_failedcase_records() sum_div = div(b('.失败用例列表'), id='mydiv2') self.page << sum_div tab_failed_case = self.page << table() self.tablecss(tab_failed_case) title_tr_failed_case = tab_failed_case << tr() self.tr_title_css(title_tr_failed_case) #add task column title title_tr_failed_case << td('用例编号') title_tr_failed_case << td('模块名称') title_tr_failed_case << td('用例说明') title_tr_failed_case << td('用例等级') title_tr_failed_case << td('测试结果') for i in range(len(failedcases)): testcase = failedcases[i] casecode = testcase['testcasename'] groupname = testcase['testgroupname'] description = testcase['description'] level = testcase['caselevel'] status = int(testcase['status']) #add column value value_tr_failed_case = tab_failed_case << tr() value_tr_failed_case << td('%s'%casecode) value_tr_failed_case << td('%s'%groupname) value_tr_failed_case << td('%s'%description.encode('utf-8')) value_tr_failed_case << td('%s'%level) if status == 0: value_tr_failed_case << td('Pass') else: value_tr_failed_case << td('Failed') self.page << br()

def gen_totalcase_report(self): totalcases = self.drp.get_totalcase_records() sum_div = div(b('.所有用例列表'), id='mydiv4') self.page << sum_div tab_total_case = self.page << table() self.tablecss(tab_total_case) title_tr_total_case = tab_total_case << tr() self.tr_title_css(title_tr_total_case) #add task column title title_tr_total_case << td('用例编号') title_tr_total_case << td('模块名称') title_tr_total_case << td('用例说明') title_tr_total_case << td('用例等级') title_tr_total_case << td('测试结果') for i in range(len(totalcases)): testcase = totalcases[i] casecode = testcase['testcasename'] groupname = testcase['testgroupname'] description = testcase['description'] level = testcase['caselevel'] status = int(testcase['status']) #add column value value_tr_total_case = tab_total_case << tr() value_tr_total_case << td('%s'%casecode) value_tr_total_case << td('%s'%groupname) value_tr_total_case << td('%s'%description.encode('utf-8')) value_tr_total_case << td('%s'%level) if status == 0: value_tr_total_case << td('Pass') else: value_tr_total_case << td('Failed') self.page << br()

def getdev_build_info(self,section='build_dev'): import os build_dev = section self.build_dev_info = config.SysConfig(self.project).getdbconnectinfo(build_dev) host = self.build_dev_info['host'] user = self.build_dev_info['user'] pwd = self.build_dev_info['password'] source = self.build_dev_info['source'] result = commonfunc.ssh_cmd(host,user,pwd,"svn info %s"%source) lresult = result.split("/r/n") url = lresult[2] reversion = lresult[5] last_author = lresult[8] last_date = lresult[10] return lresult

def genbuildreport(self): dev_info = self.getdev_build_info('build_dev') test_info = self.getdev_build_info('build_test') build_div = div(b('.版本信息'), id='mydiv5') self.page << build_div tab_build = self.page << table()

self.tablecss(tab_build,'70%') title_tr_build = tab_build << tr() self.tr_title_css(title_tr_build) #add task column title title_td = title_tr_build << td('开发代码版本信息') title_td.attributes['colspan'] = '1'; #add column value value_tr_build = tab_build << tr() td_dev = value_tr_build << td() #td_dev.attributes['font'] = 'size =1' td_dev = td_dev << font() td_dev.attributes['size'] = '2' pt = td_dev << p() pt << dev_info[2].strip() pt <<br() pt << dev_info[5].strip() pt <<br() pt <<dev_info[8].strip() pt <<br() pt <<dev_info[10].strip() title_tr_build = tab_build << tr() self.tr_title_css(title_tr_build) #add task column title title_td = title_tr_build << td('测试代码版本信息') title_td.attributes['colspan'] = '1'; #add column value value_tr_build = tab_build << tr() td_test = value_tr_build << td() td_test = td_test << font() td_test.attributes['size'] = '2' pt = td_test << p() pt << test_info[2].strip() pt <<br() pt << test_info[5].strip() pt <<br() pt << test_info[8].strip() pt <<br() pt << test_info[10].strip() pt <<br() self.page << br()

def genreport(self,filename='test.html'): self.genbuildreport() self.gentask_html() self.gengroupreport() self.gen_failedcase_report() self.gen_totalcase_report() self.page.printOut('test.html')

if __name__ == '__main__': file = 'first.html' rp = report(suitid=12) rp.genreport(file)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档