51Testing软件测试论坛

标题: 粗暴解决 HTMLTestRunner 加入截图展示功能 [打印本页]

作者: lsekfe    时间: 2016-6-21 16:13
标题: 粗暴解决 HTMLTestRunner 加入截图展示功能
  1. 最近使用appium+python来做自动化,测试报告用的网上共享的HTMLTestRunner模块,但是里面貌似没有展示截图的功能,于是自己动手稍微修改了一下!
  2. 先上成果图,点击图片名字就能打开图片


  3. 总体思路为:在HTMLTestRunner的report模板中加入一列picture,然后将用来展示图片的html打印到每个case的日志中,再从日志中将这段文字截取出来放入report中(主要是为了简单粗暴的将每个case与相关截图正确对应起来~想不到其他办法啦!欢迎高手们给出更加简单快捷的办法~)
  4. 以下为我的操作方法,有点长~
  5. 一、在HTMLTestRunner.py里的原有的html表格中插入了一列picture(在<td>View</td>下面加入一行<td>Picture</td>,在<td> </td>下加入一行<td><a href="" target="_blank"></a></td>即可),用来展示脚本中的截图超链接

  6. <tr id='header_row'>
  7.     <td>Test Group/Test case</td>
  8.     <td>Count</td>
  9.     <td>Pass</td>
  10.     <td>Fail</td>
  11.     <td>Error</td>
  12.     <td>View</td>
  13.     <td>Picture</td>
  14. </tr>
  15. %(test_list)s
  16. <tr id='total_row'>
  17.     <td>Total</td>
  18.     <td>%(count)s</td>
  19.     <td>%(Pass)s</td>
  20.     <td>%(fail)s</td>
  21.     <td>%(error)s</td>
  22.     <td> </td>
  23.     <td><a href="" target="_blank"></a></td>
  24. </tr>
  25. </table>
  26. 二、还是在HTMLTestRunner.py里插入一行%(html)s来放置对应脚本的截图

  27.     REPORT_TEST_WITH_OUTPUT_TMPL = r"""
  28. <tr id='%(tid)s' class='%(Class)s'>
  29.     <td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
  30.     <td colspan='5' align='center'>

  31.     <!--css div popup start-->
  32.     <a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >
  33.         %(status)s</a>

  34.     <div id='div_%(tid)s' class="popup_window">
  35.         <div style='text-align: right; color:red;cursor:pointer'>
  36.         <a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >
  37.            [x]</a>
  38.         </div>
  39.         <pre>
  40.         %(script)s
  41.         </pre>
  42.     </div>
  43.     <!--css div popup end-->

  44.     </td>
  45.     %(html)s
  46. </tr>

  47. 三、依然在HTMLTestRunner.py中,_generate_report_test()函数中,插入html的内容,因为本身初学者,对unittest和htmltestrunner都不怎么了解,观察htmltestrunner的报告发现它能展示脚本执行过程中打印的log文本,所以我强行把自己组装的用于展示图片html代码打印到执行日志中,然后通过关键字截取出来,放置在script后面的位置,也就是刚才新建的picture列(要是觉得最后report中打印的log中加入了这段html影响美观,可以在下面代码中script里删掉~我懒得写了~)

  48.         script = self.REPORT_TEST_OUTPUT_TMPL % dict(
  49.             id = tid,
  50.             output = saxutils.escape(uo+ue),
  51.         )

  52.         s = uo+ue
  53.         html = s[s.find('htmlbegin')+9:s.find('htmlend')]

  54.         row = tmpl % dict(
  55.             tid = tid,
  56.             Class = (n == 0 and 'hiddenRow' or 'none'),
  57.             style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),
  58.             desc = desc,
  59.             script = script,
  60.             html = html,
  61.             status = self.STATUS[n],
  62.         )
  63. 四、在自己封装的手机截屏方法中加入分别将截图名称和截图存放路径插入对应的数组中(也可以使用二维数组),以下分别为打印日志,截屏,组装html的方法,在组装完成的html代码开头和结尾分别叫上htmlbegin和htmlend作为之后截取使用的关键字

  64. # _*_ coding:utf-8 _*_
  65. __author__ = 'gjj14453'
  66. import logging
  67. import os
  68. import common.myDate as myDate


  69. PATH = lambda p: os.path.abspath(
  70.     os.path.join(os.path.dirname(__file__), p))


  71. pics = []
  72. picpath = []


  73. ##################################
  74. #  日志
  75. # 0: debug
  76. # 1:info
  77. # 2:warning
  78. # -1:error
  79. ###################################
  80. def mylogger(msg, flag=1):
  81.     logging.basicConfig(level=logging.INFO,
  82.                     format='%(asctime)s %(filename)s %(levelname)s %(message)s',
  83.                     datefmt='%a, %d %b %Y %H:%M:%S',
  84.                     filename='mylog.log',
  85.                     filemode='w')
  86.     console = logging.StreamHandler()
  87.     console.setLevel(logging.DEBUG)
  88.     formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
  89.     console.setFormatter(formatter)
  90.     logging.getLogger('').addHandler(console)
  91.     if flag == 0:
  92.         logging.debug(msg)
  93.     elif flag == 1:
  94.         logging.info(msg)
  95.     elif flag == 2:
  96.         logging.warning(msg)
  97.         screenshot()
  98.     elif flag == -1:
  99.         logging.error(msg)
  100.         screenshot()
  101.     logging.getLogger('').removeHandler(console)


  102. #  截屏
  103. def screenshot():
  104.     dirname = PATH('D:\\MyConfiguration\\gjj14453\\PycharmProjects\\untitled\\list_out' + "/screenshot")
  105.     os.popen("adb wait-for-device")
  106.     os.popen("adb shell screencap -p /data/local/tmp/tmp.png")
  107.     if not os.path.isdir(dirname):
  108.         os.makedirs(dirname)
  109.     pic = myDate.timestampname() + ".png"
  110.     path = dirname + "/" + pic
  111.     os.popen("adb pull /data/local/tmp/tmp.png " + PATH(path))
  112.     os.popen("adb shell rm /data/local/tmp/tmp.png")
  113.     mylogger("截图为:" + pic)
  114.     pics.append(pic)
  115.     picpath.append(path)


  116. def creathtml(path, pic):
  117.     html = ''
  118.     if range(len(path)) > 0:
  119.         for i in range(len(path)):
  120.             if i == 0:
  121.                 html = '<a href=' + path[i] + ' target="_blank">' + pic[i] + '</a>'
  122.             else:
  123.                 html = html + '<br /><a href=' + path[i] + ' target="_blank">' + pic[i] + '</a>'
  124.     else:
  125.         html = ''
  126.     htmls = 'htmlbegin<td>' + html +'</td>htmlend'
  127.     return htmls
  128. 五、之后在case中加入打印html到日志中的语句就OK啦

  129. class Test(unittest.TestCase):

  130.     def setUp(self):
  131.         log.picpath = []
  132.         log.pics = []
  133.         pass

  134.     def tearDown(self):
  135.         pass

  136.     def test(self):
  137.         log.mylogger('aaa', -1)
  138.         log.mylogger('bbb', -1)
  139.         log.mylogger(log.creathtml(log.picpath, log.pics))
  140. 最后,还是希望有高手能给我一个更加简单的插入对应截图的办法~本来想把截图存放的数组传到脚本执行的result中再一一提取,试了几次毫无成果~
复制代码

文章出自:https://testerhome.com/topics/4620


作者: 若尘_51    时间: 2016-6-21 16:29
学习一下, 膜拜大侠大神。 顶~   
作者: 254761258    时间: 2017-7-7 14:03
最近正好在这里遇到问题了,
想问下楼主
def test(self):
        log.mylogger('aaa', -1)
        log.mylogger('bbb', -1)
        log.mylogger(log.creathtml(log.picpath, log.pics))
这里的‘aaa’,‘bbb’是什么参数,是一个固定的字符串?还是什么?;test方法中的执行用例写哪里呢?




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2