1. HTML测试报告

对测试人员来而言,测试的产出很难衡量。换句话说,测试人员的价值比较难以量化和评估,相信这一点对软件测试人员来说深有体会。我们花费了很多时间与精力所做的自动化测试也是如此。所以,需要一份漂亮且通俗易懂的测试报告来展示自动化测试成果。显然,一份简单的Log文件是不够的。

HTMLTestRunner是Python标准库unittest单元测试框架的一个扩展,它生成易于使用的HTML测试报告。HTMLTestRunner是在BSD许可证下发布的。

下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

这个扩展非常简单,只有一个HTMLTestRunner.py文件,被选中后单击鼠标右键,在弹出的快捷菜单中选择另存为,将它保存到本地。安装方法也很简单,将其复制到Python安装目录下即可。

Windows:将下载的文件保存到...\Python36\Lib目录下。pycharm中不能使用,就找到pycharm的lib目录,将文件粘贴进去。

Linux:以Ubuntu为例,首先需要打开终端,找到Python的安装目录。打开终端后,输入Python命令进入Python交互模式,通过sys.path可以查看本机python的安装目录。以root身份将HTMLTestRunner.py文件复制到/usr/local/Python3.6/dist-packages/目录下。在Python交互模式下引用HTMLTestRunner模块,如果系统没有报错,则说明添加成功。

1.1 修改HTMLTestRunner

因为HTMLTestRunner.py是基于Python 2开发的,为了使其支持Python 3的环境,需要对其中的部分内容进行修改。下面通过编辑器打开HTMLTestRunner.py文件。

#第94行
import StringIO
修改为:
import io #第539行
self.outputBuffer = StringIO.StringIO()
修改为:
self.outputBuffer = io.StringIO() #631行
print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
修改为:
print (sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)) #第642行
if not rmap.has_key(cls):
修改为:
if not cls in rmap: #第766行
uo = o.decode('latin-1')
修改为:
uo = e #第772行
ue = o.decode('latin-1')
修改为:
ue = e

1.2 生成HTML测试报告

下面继续以test_baidu.py文件为例生成HTMLTestRunner测试报告。

from selenium import webdriver
import unittest
from HTMLTestRunner import HTMLTestRunner
from time import sleep class Baidu(unittest.TestCase): def setUp(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(10)
self.base_url = "http://www.baidu.com" def test_baidu_search(self):
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_id("kw").send_keys("HTMLTestRunner")
driver.find_element_by_id("su").click()
sleep(5) def tearDown(self):
self.driver.quit() if __name__ == "__main__":
testunit = unittest.TestSuite()
testunit.addTest(Baidu("test_baidu_search")) #定义报告存放路径
fp = open('./result.html','wb')
#定义测试报告
runner = HTMLTestRunner(stream=fp,
title='百度搜索测试报告',
description='用例执行情况:',
verbosity=2
)
runner.run(testunit) #运行测试用例
fp.close() #关闭报告文件

首先,将HTMLTestRunner模块用import导入进来。

其次,通过open()方法以二进制写模块打开当前目录下的result.html,如果没有,则自动裁剪该文件。

接着,调用HTMLTestRunner模块下的HTMLTestRunner类。stream指定测试报告文件,title用于定义测试报告的标题,description用于定义测试报告的副标题。

最后,通过HTMLTestRunner的run()方法来运行测试套件中所组装的测试用例。最后通过close()关闭测试报告文件。

用例运行完毕,打开当前目录下的“result.html”文件查看生成的测试报告。

1.3 更易读的测试报告

现在生成的测试报告还不易读,因为它只罗列了一堆测试类和测试方法,我们需要用心的位测试类和测试方法命名才能提高测试报告的可读性,如果随意命名为“test_case1”、“test_case2”等,那么这份报告就失去了可读性,也许时间久了连脚本开发者都不清楚“test_case1”是测试什么功能了。

在编写功能测试用例时,每条测试用例都有标题,那么我们能不能也为自动化测试用例加上标题呢?在此之前我们先来学习另外一个知识点:Python的注释。Python的注释有两种,一种叫comment,另一种叫doc string,前者为普通的注释,后者用于函数、类和方法的描述。

在类或方法的下方,通过三引号(""" """或"" "")来添加doc string类型的注释,这类注释在平时调用的时候不显示,可以通过help()方法来查看类或方法的这种注释。

回到问题的原点,HTMLTestRunner可以读取doc string类型的注释。所以我们只需给测试类或方法添加这种类型的注释即可。

class Baidu(unittest.TestCase):
''' 百度搜索测试 ''' def test_baidu_search(self):
''' 搜索关键字:HTMLTestRunner '''

再次运行测试用例,查看测试报告。

1.4 测试报告文件名

在每次运行测试之前,都要手动修改报告的名称,如果忘记修改,就会把之前的报告覆盖,这样做显得很麻烦,那么有没有办法可以使每次删除的报告名称都不重复并且有意义呢?最好的方法是在报告名称中加入当前时间,这样生成的报告既不会重叠,又能更清晰的知道报告生成的时间。

Python的time模块中提供了丰富的关于时间操作的方法,可以利用这些方法来完成这个需求。

time.time():获取当前时间戳。

time.ctime():当前时间的字符串形式。

time.localtime():当前时间的struct_time形式。

time.strftime():用来获得当前时间,可以将时间格式化为字符串。

Python中时间日期格式化符号(区分大小写)。

%y 两位数的年份表示(00-99)

%Y 四位数的年份表示(000-9999)

%m 月份(01-12)

%d 月内中的一天(0-31)

%H 24小时制小时数(0-23)

%I 12小时制小时数(01-12)

%M 分钟数(00=59)

%S 秒(00-59)

%a 本地简化星期名称

%A 本地完整星期名称

%b 本地简化的月份名称

%B 本地完整的月份名称

%c 本地相应的日期表示和时间表示

%j 年内的一天(001-366)

%p 本地A.M.或P.M.的等价符

%U 一年中的星期数(00-53)星期天为星期的开始

%w 星期(0-6),星期天为星期的开始

%W 一年中的星期数(00-53)星期一为星期的开始

%x 本地相应的日期表示

%X 本地相应的时间表示

%Z 当前时区的名称

%% %号本身

继续打开测试用例,做如下修改。

import time

#.............

if __name__ == "__main__":
testunit = unittest.TestSuite()
testunit.addTest(Baidu("test_baidu_search")) #按照一定格式获取当前时间
now = time.strftime("%Y-%m-%d %H_%M_%S") #定义报告存放路径
filename = './'+now+'result.html'
fp = open(filename,'wb')
#定义测试报告
runner = HTMLTestRunner(stream=fp,
title='百度搜索测试报告',
description='用例执行情况:',
verbosity=2
)
runner.run(testunit) #运行测试用例
fp.close() #关闭报告文件

通过strftime()方法以指定的格式获取当前时间,将当前时间的字符串赋值给now变量。将now通过加号(+)拼接到生成的测试报告的文件名中。再次运行测试用例,生成测试报告。

1.5 项目集成测试报告

目前HTMLTestRunner只是针对单个测试文件生成测试报告,我们的最终目的是希望将它集成到runtest.py文件中,使其作用于整个测试项目。下面打开runtest.py文件进行修改,还有就是把test_baidu.py改回来。

import unittest
from HTMLTestRunner import HTMLTestRunner
import time #指定测试用例为当前文件夹下的test_case目录
test_dir = './test_case'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test_*.py') if __name__ == "__main__":
# 按照一定格式获取当前时间
now = time.strftime("%Y-%m-%d %H_%M_%S") # 定义报告存放路径
filename = './' + now + 'result.html'
fp = open(filename, 'wb')
# 定义测试报告
runner = HTMLTestRunner(stream=fp,
title='百度搜索测试报告',
description='用例执行情况:',
verbosity=2
)
runner.run(discover) # 运行测试用例
fp.close() # 关闭报告文件

生成的HTML测试报告:

Selenium(十八):unittest单元测试框架(四) HTML测试报告的更多相关文章

  1. Selenium(十七):unittest单元测试框架(三) 脚本分析、编写Web用例

    1. 带unittest的脚本分析 也许你现在心里还有疑问,unittest框架与我们前面所编写的Web自动化测试之间有什么必然联系吗?当然有,既然unittest可以组织.运行测试用例,那么为什么不 ...

  2. Selenium(十六):unittest单元测试框架(二) 初识unittest(续)

    1. 认识unittest(续) 关于unittest单元测试框架,还有一些问题值得进一步探讨.你可能在前一章的学习过程中产生了一些疑问,也许你会在本节中找到答案. 1.1 用例执行的顺序 用例的执行 ...

  3. Selenium实战(四)——unittest单元测试框架1

    Python中的单元测试框架包含:doctest.unittest.pyttest.nose等,使用unittest单元测试框架不需要自行定义断言失败的提示,并且当一个测试函数执行失败后,后面的测试函 ...

  4. Selenium(十五):unittest单元测试框架(一) 初识unittest

    1. 认识unittest 什么是单元测试?单元测试负责对最小的软件设计单元(模块)进行验证,它使用软件设计文档中对模块的描述作为指南,对重要的程序分支进行测试以发现模块中的错误.在python语言下 ...

  5. 四. 引入unittest单元测试框架

    1.   安装 SeleniumIDE(firefox) (1)下载地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/ (2 ...

  6. Selenium+Python ---- 免登录、等待、unittest单元测试框架、PO模型

    1.免登录在进行测试的过程中难免会遇到登录的情况,给测试工作添加了工作量,本文仅提供一些思路供参考解决方式:手动请求中添加cookies.火狐的profile文件记录信息实现.人工介入.万能验证码.去 ...

  7. Python+selenium之简单介绍unittest单元测试框架

    Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...

  8. Python+Selenium框架设计篇之-简单介绍unittest单元测试框架

    前面文章已经简单介绍了一些关于自动化测试框架的介绍,知道了什么是自动化测试框架,主要有哪些特点,基本组成部分等.在继续介绍框架设计之前,我们先来学习一个工具,叫unittest.       unit ...

  9. Python+Selenium ----unittest单元测试框架

    unittest是一个单元测试框架,是Python编程的单元测试框架.有时候,也做叫做“PyUnit”,是Junit的Python语言版本.这里了解下,Junit是Java语言的单元测试框架,Java ...

随机推荐

  1. excel中生成32位随机id

    记录下如何在EXCEL中利用公式生成32位的随机id(无符号,只有数字和小写字母). ,,)),),"",DEC2HEX(RANDBETWEEN(,,)),),"&quo ...

  2. Docker network整理

    一.简介 默认情况下容器与容器.容器与宿主机的网络是隔离开来的, 当你安装docker的时候,docker会创建一个桥接器docker0,通过它才让容器与容器.容器与宿主机之间通信. Docker安装 ...

  3. python网络编程socket编程(TCP、UDP客户端服务器)

    摘录 python核心编程 使用socket()模块函数创建套接字——通信端点 >>> from socket import * >>> tcpSock = soc ...

  4. 敏捷之旅--携程行程&订单团队

    转自本人运营的公众号“ 携程技术中心PMO”(ID:cso_pmo)     关于我们   我们面临的挑战   敏捷开发是以用户的需求进化为核心,采用迭代.循序渐进的方法进行软件开发.先把一个大项目分 ...

  5. global、nonlocal关键字

    一:global:在函数内部引用/声明全局变量 在自定义函数时,有时候需要引用函数外的一些全局变量,如果不需要修改全局变量的内容,则可以直接引用,像下面这样: c = 999 def func(): ...

  6. 【转】CAP 定理的含义

    原文链接:CAP 定理的含义 作者: 阮一峰 日期: 2018年7月16日 分布式系统(distributed system)正变得越来越重要,大型网站几乎都是分布式的. 分布式系统的最大难点,就是各 ...

  7. IT兄弟连 HTML5教程 W3C盒子模型

    日常生活中所见的盒子也就是能装东西的一种箱子,如果家里的东西很多,那么就需要按类别装到不同的箱子中.网页中的内容表现也是一样的,如果页面内容比较多,又想让页面更整洁.更美观.有很好的用户体验,则也需要 ...

  8. java8新特性之——lambda表达式的使用

    lambda表达式简介 个人理解,lambda表达式就是一种新的语法,没有什么新奇的,简化了开发者的编码,其实底层还是一些常规的代码.Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解 ...

  9. Centos 下安装 PHP (新)

    今天重新实践了下 CentOS 7.6 下安装 PHP7 并完成配置,总结了一条可以照其实现的套路. 安装 PHP 所需扩展 # yum install libxml2 libxml2-devel o ...

  10. SpringMVC框架之第四篇

    5.SpringMVC异常处理 5.1.异常分类 1.可预知异常: Java编译时可检测异常,例如:IOException.SQLException等. 自定义异常(继承Exception父类的自定义 ...