一、unittest框架是什么?
unittest是python自带的一个单元测试框架,也是python里面最基本的单元测试框架.存放在Python安装目录下的lib目录下
二、unittest里面最核心的四个概念:
1.test case 测试用例
2.test fixture 测试夹具
3.test runner 测试执行
4.test suite 测试套件
三、unittest的书写规则
1.测试文件必须以 test 开头 如:test_01_unittest入门脚本.py
2.测试类必须继承 unittest.TestCase 类
3.测试类必须以 Test 开头 如:class TestLogin(unittest.TestCase)
4.测试方法,最好以 test 开头 如:def test_01_login(self)
5.在测试的py文件里面去执行代码 unittest.main()
6.在测试类里面 可以有普通方法,但是普通的方法需要被测试方法调用
四、具体操作
1、unittest入门脚本
import unittest
class TestLogin(unittest.TestCase):
def test_login(self):
"""普通登录"""
print("普通的登录测试")
def test_login_remember(self):
"""记住登录"""
print("记住保存信息登录")
if __name__ == '__main__':
unittest.main()
2、fixture测试夹具
方法级别:
setup() 在每一个测试方法执行之前执行 setup 的代码
teardown() 在每一个测试方法执行之后执行 teardown 的代码
类级别:
setupClass() 在每一个测试类执行之前执行的方法 需要使用@classmethod装饰
teardownClass() 在每一个测试类执行之后执行的方法 需要使用@classmethod装饰
import unittest
class Test_login2(unittest.TestCase):
def test_login(self):
print('普通的登录测试')
def test_login_remember(self):
print("记住密码登录")
def setUp(self):
print("setUp执行的代码,在每一个测试方法执行之前执行")
def tearDown(self) -> None:
print("teardown执行的代码,在每一个测试方法执行之后执行")
@classmethod
def setUpClass(cls) -> None:
print("stupClass执行的代码,在整个测试类执行之前开始执行")
@classmethod
def tearDownClass(cls) -> None:
print("teardownClass执行的代码,在整个测试类执行之后开始执行")
if __name__ == '__main__':
unittest.main()
3、用例执行顺序
在unittest里面,用例的执行顺序默认是按照 ASCII 码的顺序
自定义测试用例的执行顺序:给每一条用例加上执行的序号
import unittest
class TestLoginPay(unittest.TestCase):
def test_01_login(self):
print('先进行登录')
def test_02_view_page(self):
print("浏览网页,挑选合适的商品")
def test_03_add_cart(self):
print("选择合适的商品加入购物车")
def test_04_create_order(self):
print("生成订单")
def test_05_pay_order(self):
print("支付订单")
if __name__ == '__main__':
unittest.main()
四、断言
判断预期和实际结果是否相符合
self.assertEqual(a,b,msg='错误描述') 判断 a==b成立则测试用例通过
self.assertTrue(x,msg='错误描述') 判断 表达式x 是否为true,为true通过测
self.assertIn(a,b,msg='错误描述') 判断 a in b成立则测试通过
import unittest
class TestLogin03(unittest.TestCase):
def test_login(self):
expected = 'admin' # 预期结果
result = "admin2" # 实际结果
print("登录测试")
self.assertEqual(expected, result, msg='登录账号错误')
def test_add_cart(self):
expected = 10
result = 9
print("添加购物车")
self.assertTrue(expected == result, msg='购物车数量不对')
def test_pay_order(self):
expected = "00122"
result = 'order0012'
print("支付订单")
self.assertIn(expected, result, msg='订单号错误')
# self.assertTrue(expected in result,msg='订单号错误')
if __name__ == '__main__':
unittest.main()
五、跳过测试
跳过测试:
1.当我们写的部分用例,在某些情况下不需要执行的时候可以跳过
2.当系统更新之后,部分的测试用例失效,但是不确定后面是否还会再改回来,就直接跳过
装饰器实现的跳过测试用例
@unittest.skip(原因) 没有条件,直接跳过
@unittest.skipIf(表达式,原因) 表达式为真跳过测试
@unittest.skipUnless(表达式,原因) 表达式为假跳过测试
import unittest
import random
# 性别 1 表示男性 0 表示女性
sex = random.randint(0,1)
class TestLoginPay(unittest.TestCase):
def test_01_login(self):
print('先进行登录')
@unittest.skip("不想花钱")
def test_02_view_page(self):
print("浏览网页,挑选合适的商品")
@unittest.skipUnless(1==2,'不加入购物车')
def test_03_add_cart(self):
print("选择合适的商品加入购物车")
@unittest.skipIf(1==2,reason='不想下单')
def test_04_create_order(self):
print("生成订单")
@unittest.skipIf(sex==1,reason='男的不想花钱,女的花钱买买买')
def test_05_pay_order(self):
print("支付订单")
if __name__ == '__main__':
unittest.main()
六、数据驱动
数据驱动:
有的用例只是参数不一样,其他代码完全一样,就可以通过改变测试参数来实现一条用例方法
执行多种不同的测试场景.在unittest里面需要使用 ddt 来提供参数化的功能
pip install ddt 安装
ddt可以参数化读取列表嵌套列表或者列表嵌套字典的数据
列表嵌套列表读取:
先在类前面加上: @ddt.ddt
在方法前面加上: @ddt.data(*列表嵌套列表)
@ddt.unpack
列表嵌套字典读取:
先在类前面加上: @ddt.ddt
在方法前面加上: @ddt.data(*列表嵌套列表)
在方法里面使用一个形式参数来接收