unittest是python内置的单元测试框架,具备编写测试用例,组织用例,执行用例,输出报告等自动化框架的条件。
一、单元测试的简介
1. 什么是单元测试?
2. 为什么要做单元测试?
二、单元测试实战
2.1 登录函数详细设计
……
【登录函数】
参数:
? 用户名、密码,用户名和密码不能为空
返回值:
? 用户名:不能为空,如果为空,返回{“code”: 0, “msg”: “所有的参数不能为空”};
? 密码:不能为空,如果为空,返回{“code”: 0, “msg”: “所有的参数不能为空”};
? 用户名错误:{“code”: 0, “msg”: “账号或密码不正确”}
? 密码错误:{“code”: 0, “msg”: “账号或密码不正确”}
? 登录成功:{“code”: 1, “msg”: “登录成功”}
……
2.2 设计测试用例
用例描述 | 输入数据 | 预期结果 | 实际结果 |
---|
账号密码正确 | | | | 账号正确,密码错误 | | | | 账号错误,密码正确 | | | | 账号为空 | | | | 密码为空 | | | |
2.3 编码
2.4 使用普通方法测试代码
2.5使用单元测试方法测试代码
三、单元测试总结
3.1 单元测试框架unittest的架构
- TestCase:一个testcase的实例就是一个测试用例:
- TestSuite:多个测试用例集合在一起。
- TestLoader:是用来加载TestCase到TestSuite中的
- TextTestRunner:用来执行测试用例的。
- fixture:包括setUp 和tearDown两个方法,分别用于创建测试环境和销毁测试环境。
3.2 使用unittest做单元测试的步骤
import unittest
class LoginCheckTest(unittest.TestCase):
def setUp(self) -> None:
print("每条用例")
def test_login(self):
self.assertEqual(0, login_check('lemon','123456').get('code'))
def test_password_error(self):
self.assertEqual(1,login_check('lemon','8888222').get('code'))
def test_user_error(self):
self.assertEqual(1, login_check('aaaabc', '123456').get('code'))
if __name__ == '__main__':
unittest.main()
运行unittest.main()时,unittest将自动执行test开头的函数,函数的运行顺序按字母顺序。
3.3 常用断言函数说明
方法 | 检查 | 功能描述 |
---|
assertEqual(self, first, second, msg=None) | a==b | 如果两个对象不相等,则失败,msg可以用来指定失败时的提示信息。 | assertNotEqual(self, first, second, msg=None): | a!=b | 断定预期结果a和实际结果b不相等。 | | | |
四、测试用例的管理
4.1 常用函数说明
函数 | 功能说明 |
---|
unittest.TestSuite() | 创建suite对象 | unittest.TestLoader() | 创建用例加载器 | unittest.TestSuite().addTest() | 向suite中添加用例 | unittest.TextTestRunner() | 创建用例运行器 | unittest.TextTestRunner().run(suite) | 使用用例运行期运行suite |
4.2 用例管理的步骤
五、如何生成测试报告
-
纯文本测试报告:
创建一个文件,以写的方式的打开
with open("test_result.txt","w") as f:
runner = unittest.TextTestRunner(fs)
runner.run(suite)
-
html类型报告: 使用BeautifulReport模块生成
环境安装: pip install BeautifulReport
使用方式
from BeautifulReport import BeautifulReport
br = BeautifulReport(suite)
br.report("登录功能单元测试报告","login__test_report.html")
完整代码如下:
import unittest
from tests.test_user import LoginCheckTest
if __name__ == '__main__':
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTest(loader.loadTestsFromTestCase(LoginCheckTest))
from BeautifulReport import BeautifulReport
br = BeautifulReport(suite)
br.report("登录功能单元测试报告", "login__test_report.html")
作业:针对下述代码,使用unittest进行测试。
users = [{'user': 'lemon', 'password': '123456'}]
def register(username, password1, password2):
if username and password1 and password2:
return {"code": 0, "msg": "所有参数不能为空"}
for user in users:
if username == user['user']:
return {"code": 0, "msg": "该账户已存在"}
else:
if password1 != password2:
return {"code": 0, "msg": "两次密码不一致"}
else:
if 6 <= len(username) >= 6 and 6 <= len(password1) <= 18:
users.append({'user': username, 'password': password2})
return {"code": 1, "msg": "注册成功"}
else:
return {"code": 0, "msg": "账号和密码必须在6-18位之间"}
if __name__=="__main__":
res = register('python14', '123456', '123456')
print(res)
"""
函数入参:
参数1:账号
参数2:密码1
参数2:密码2
注意点:这里的参数都是字符串类型,不需要考虑其他类型。
函数内部处理的逻辑:
判断是否有参数为空,
判断账号是否被注册过,
判断账号密码是否在6-18位之间,
判断两个密码是否一致。
上面添加都校验通过才能注册成功,其他情况都注册失败,
对应的返回结果如下:
注册成功 返回结果:{"code": 1, "msg": "注册成功"}
有参数为空, 返回结果 {"code": 0, "msg": "所有参数不能为空"}
两次密码不一致 返回结果:{"code": 0, "msg": "两次密码不一致"}
账户已存在 返回结果:{"code": 0, "msg": "该账户已存在"}
密码不在6-18位之间 返回结果:{"code": 0, "msg": "账号和密码必须在6-18位之
间"} 账号不在6-18位之间 返回结果:{"code": 0, "msg": "账号和密
码必须在6-18位之间"}
作业要求:请设计用例,对此功能函数进行单元测试,
上面已经被注册的账号:lemon
提示:不需要去关注功能函数内部的代码,也不要改里面的代码,直接复制过去就好,函数内部有bug, 自己设计用例去测。
|