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测试报告: