2.单元测试unittest
Python里面也有单元测试框架-unittest,相当于是一个Python版的junit。Python里面的单元测试框架除了unittest,还有一个pytest框架,这个用的比较少.
2.1 unittest执行顺序
测试用例那么多,那用例是按什么规则运行的呢?
实例:
import unittest
import time
class Test(unittest.TestCase):
def setUp(self):
print "start!"
def tearDown(self):
time.sleep(1)
print "end!"
def test01(self):
print "执行测试用例01"
def test03(self):
print "执行测试用例03"
def test02(self):
print "执行测试用例02"
def addtest(self):
print "add方法"
if __name__ == "__main__":
unittest.main()
总结
1.执行顺序:
start!-执行测试用例01-end!
start!-执行测试用例02-end!
start!-执行测试用例03-end!
2.从执行结果可以看出几点
先执行的前置setUp,然后执行的用例(test*),最后执行的后置tearDown
测试用例(test*)的执行顺序是根据01-02-03执行的,也就是说根据用例名称来顺序执行的
addtest(self)这个方法没执行,说明只执行test开头的用例
2.2 unittest装饰器
从2.1的例子可以看到start和end,执行了三次,如果用例有几百上千条时,如果这样执行,那就会浪费很多时间。有没有办法,start和end只需要执行一次,就需要用到装饰器。装饰器为:@classmethod
实例:
import unittest
import time
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):# 括号内cls是可任一写,习惯写成cls
print "start!"
@classmethod
def tearDownClass(cls):
time.sleep(1)
print "end!"
def test01(self):
print "执行测试用例01"
def test03(self):
print "执行测试用例03"
def test02(self):
print "执行测试用例02"
def addtest(self):
print "add方法"
if __name__ == "__main__":
unittest.main()
运行结果:
start!
执行测试用例01
执行测试用例02
执行测试用例03
...end!
从执行结果可以看出,前置和后置在执行用例前只执行了一次。
一、用setUp与setUpClass区别
1.setup():每个测试case运行前运行
2.teardown():每个测试case运行完后执行
3.setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
4.tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次
5.@是修饰符,classmethod是Python里的类方法
2.3 unittest批量执行
我们在执行用例时,单个少量的用例好执行,那么有多个脚本的时候,如何批量执行呢?这时候就需要用到unittest里面的discover方法来加载用例了。
第一步:新建测试项目
- pycharm左上角File>New Projetc,在location位置命名一个测试工程的名称:laozhutest,然后保存
- 选中刚才新建的工程右键>New>Python Package>新建一个文件夹,如:baidu
3.重复第2个步骤再建一个add文件夹,里面分别有两个用例的脚本,如下图所示。
test_01,test_02,test_03,test_04是我们写用例的脚本
- 在laozhutest右键创建一个脚本run_all_case.py,接下来用这个脚本去批量执行所有的用例。
二、diascover加载测试用例
1.discover方法里面有三个参数:
case_dir:这个是待执行用例的目录。
pattern:这个是匹配脚本名称的规则,test*.py意思是匹配test开头的所有脚本。
top_level_dir:这个是顶层目录的名称,一般默认等于None就行了。
2.discover加载到的用例是一个list集合,需要重新写入到一个list对象testcase里,这样就可以用unittest里面的TextTestRunner这里类的run方法去执行。
三、run测试用例
1.为了更方便的理解,可以把上面discover加载用例的方法封装下,写成一个函数
2.4 unittest生成测试报告
批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的。
unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLTestRunner
一、导入HTMLTestRunner
1.这个模块下载不能通过pip安装了,只能下载后手动导入,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html
2.Download下HTMLTestRunner.py文件就是我们需要下载的包。
3.下载后复制到Python安装文件的Lib目录下
二、生成html测试报告
1.这里主要有三个参数:
stream:测试报告写入文件的存储区域
title:测试报告的主题
description:测试报告的描述
- report_path是存放测试报告的地址
运行脚本后在F盘指定位置就能找到这个测试报告文件,这时候如果文件多了,不知道测试报告在哪天生成的?能否在文件名上显示一个日期和时间呢?当然是可以的!
备注:
%Y-%m-%d为年月日
%H-%M为时分 注意:时间之间不能使用冒号(:)因为文件名不能使用冒号
三、测试报告详情
1.找到测试报告文件,用浏览器打开,点开View里的Detail可以查看详情描述。
红框中内容显是英文,我们不能直观看出是什么测试用例,可以在测试代码中添加中文注释,注释前面要加字母u,代码修改如下:
四、再次运行run_all_case脚本文件后,查看HTML测试报告
2.5 unittest断言
Python在 unittest.TestCase 类中提供了很多断言方法。断言方法检查你认为应该满足的条件是否确实满足。如果该条件确实满足,你对程序行为的假设就得到了确认,你就可以确信其中没有错误。如果你认为应该满足的条件实际上并不满足,Python将引发异常。下表描述了6个常用的断言方法。使用这些方法可核实返回的值等于或不等于预期的值、返回的值为 True 或 False 、返回的值在列表中或不在列表中。你只能在继承 unittest.TestCase 的类中使用这些方法。
unittest常用的断言方法 |
|
方法 |
用途 |
assertEqual(a, b) |
核实 a == b |
assertNotEqual(a, b) |
核实 a != b |
assertTrue(x) |
核实 x 为 True |
assertFalse(x) |
核实 x 为 False |
assertIn( item , list ) |
核实 item 在 list 中 |
assertNotIn( item , list ) |
核实 item 不在 list 中 |
三、unittest常用的断言方法
1.assertEqual(self, first, second, msg=None)
--判断两个参数相等:first == second
2.assertNotEqual(self, first, second, msg=None)
--判断两个参数不相等:first != second
3.assertIn(self, member, container, msg=None)
--判断是字符串是否包含:member in container
4.assertNotIn(self, member, container, msg=None)
--判断是字符串是否不包含:member not in container
5.assertTrue(self, expr, msg=None)
--判断是否为真:expr is True
6.assertFalse(self, expr, msg=None)
--判断是否为假:expr is False
7.assertIsNone(self, obj, msg=None)
--判断是否为None:obj is None
8.assertIsNotNone(self, obj, msg=None)
--判断是否不为None:obj is not None
实例:assertEqual(a, b),其它的断言方法请自行偿试)
2.6 Python与unittest区别
重点:
Python模式运行后,才会出现测试报告
unittest模式运行后,不会出现测试报告