python 生成html测试报表三步曲

最近把测试框架优化了一下,原本生成的报表时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)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值