python动态生成html报表_python 生成html测试报表

转自:

http://linkyou.blog.51cto.com/1332494/751799/

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

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

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

phy源码如下

# @file: pyh.py

# @purpose: a HTML tag generator

# @author: Emmanuel Turlay

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

__version__ = '$Revision: 43 $'

__date__ = '$Date$'

from sys import _getframe, stdout, modules, version

nOpen={}

nl = '/n'

doctype = 'ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd%22%3E/n" "="" style="padding:0px;margin:0px;color:#2D3236;text-decoration:none;">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">/n'

charset = '/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 = '' % (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 << ''

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 <

pt << dev_info[5].strip()

pt <

pt <

pt <

pt <

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 <

pt << test_info[5].strip()

pt <

pt << test_info[8].strip()

pt <

pt << test_info[10].strip()

pt <

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值