python UnitTest单元测试框架浅谈
在python中有python自带的unittest单元测试框架,相对于pytest而言更加简单,那让我们一起来了解一下unittest吧~ **单元测试:**意思就是对单个模块或者单个类/单个函数的测试(代码版本的测试用例)
首先,我们对要进行的测试的模块编写测试用例,这里拿账号密码登陆举例,首先列举出测试用例,这里和功能的测试用例是一样的
def logn_check(username=None,password=None):
"""
登陆校验的函数
:param username: 账号
:param password: 密码
:return:
"""
if username != None and password != None:
if username == "python38" and password == "lemonban":
return {"code": 0,"msg": "登陆成功"}
else:
return {"code": 1,"msg": "账号密码错误"}
else:
return {"code": 1,"msg": "账号密码不可为空"}
"""
1、账号密码正确
入参:账号 "python38",密码 "lemonban"
预期结果:{"code": 0,"msg": "登陆成功"}
实际结果:
2、账号正确,密码错误
入参:账号 "python38",密码 "123"
预期结果:{"code": 1,"msg": "账号密码错误"}
实际结果:
3、账号错误,密码正确
入参:账号 "python",密码 "lemonban"
预期结果:{"code": 1,"msg": "账号密码错误"}
实际结果:
4、账号为空,密码正确
入参:账号 " ",密码 "lemonban"
预期结果:{"code": 1,"msg": "账号密码不可为空"}
实际结果:
5、账号正确,密码为空
入参:账号 "python38",密码 " "
预期结果:{"code": 1,"msg": "账号密码不可为空"}
实际结果:
"""
UnitTest四大核心理念 1、TestCase测试用例) —> TestLoader(收集用例至测试套件) 2、TestSuite(测试套件) 3、TextTestRunner(执行用例 + 呈现结果) 4、Fixture(前置后置)
编写用例 —> 收集用例 —> 执行用例 —> 呈现结果
上面列举出来了五条测试用例,下面我们定义一个新的py文件来测试这个模块吧~ 编写步骤: 1、导入unittest模块以及被测文件或者其中的类 2、定义测试类,继承Unittest.TestCase 3、定义测试函数,函数名以 test_ 开头(每一个 test_ 开头的函数,为一条测试用例) 编写用例: 1、测试数据 2、测试步骤 3、断言:预期结果与实际结果比对 4、前置后置(fixture) - 前置条件、后续工作
以下面代码为例:
from Unittest_2021_07.login import logn_check
import unittest
class Testlogin(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print("Testlogin类下的用例开始执行")
@classmethod
def tearDownClass(cls) -> None:
print("Testlogin类下的用例执行完毕")
def setUp(self) -> None:
print("====单个用例开始执行====")
def tearDown(self) -> None:
print("====单个用例结束执行====")
def test_login_ok(self):
res = logn_check("python38","lemonban")
self.assertEqual(res,{"code": 0,"msg": "登陆成功"},msg="-2")
def test_login_wrong_password(self):
res = logn_check("python38", "123")
self.assertEqual(res,{"code": 1,"msg": "账号密码错误"})
def test_login_wrong_user(self):
res = logn_check("python","lemonban")
self.assertEqual(res,{"code": 1,"msg": "账号密码错误"})
def test_login_no_user(self):
res = logn_check(None,"lemonban")
self.assertEqual(res,{"code": 1,"msg": "账号密码不可为空"})
def test_login_no_password(self):
res = logn_check("python38",None)
self.assertEqual(res,{"code": 1,"msg": "账号密码不可为空"})
setUpClass, tearDownClass方法 (执行测试类的前置与后置),就是类下面第一条用例执行之前,会执行 setUpClass 方法,最后一条用例执行之后,会执行 tearDownClass 方法
@classmethod
def setUpClass(cls) -> None:
print("Testlogin类下的用例开始执行")
@classmethod
def tearDownClass(cls) -> None:
print("Testlogin类下的用例执行完毕")
setUp, tearDown方法 (执行单条测试用例的前置与后置),就是类下面每一条测试用例执行之前先执行 setUp 方法,每一条用例执行之后会执行 tearDown 方法
def setUp(self) -> None:
print("====单个用例开始执行====")
def tearDown(self) -> None:
print("====单个用例结束执行====")
下面五条就是测试用例了,调用logn_check()方法并传参,随后使用断言self.assertEqual()方法判断预期结果与实际结果是否一致
def test_login_ok(self):
res = logn_check("python38","lemonban")
self.assertEqual(res,{"code": 0,"msg": "登陆成功"},msg="-2")
这里可以使用ddt方法,当存在多组测试数据用同一套测试流程时,使用数据驱动(参数化)
import ddt
dates =[
{"username":"python38", "password":"lemonban", "except":{"code": 0,"msg": "登陆成功"}},
{"username":"python38", "password":"123", "except":{"code": 1,"msg": "账号密码错误"}},
{"username":"python", "password":"lemonban", "except":{"code": 1,"msg": "账号密码错误"}},
{"username":None, "password":"lemonban", "except":{"code": 1,"msg": "账号密码不可为空"}},
{"username":"python38", "password":None, "except":{"code": 1,"msg": "账号密码不可为空"}}
]
@ddt.ddt()
class Testlogin(unittest.TestCase):
@ddt.data(*dates)
def test_login_ok(self,case):
res = logn_check(case["username"],case["password"])
self.assertEqual(res,case["except"])
ddt模块使用: 1、首先导入ddt模块 2、在继承了unittest.TestCase的类前加 @ddt.ddt() 3、在测试用例方法前加 @ddt.data(dates),这里的dates是拆包,(*dates)会将多组测试数据依此传给一个测试流程 4、在测试函数例增加参数,随后在函数体内之前取列表的值
这样就把多组测试用例放到一个测试流程里了,极大的提升了效率,后续增加用例直接在测试数据里添加即可
下面我们就可以把用例收集到测试套件里,并运行生成报告了,这里我们再单独创建一个TestSuite类:
import os
import unittest
fs = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(fs)
s = unittest.TestLoader().discover(fs)
print(type(s))
print(s)
from HTMLTestRunner import HTMLTestRunner
runnner = HTMLTestRunner(output=".", report_name="report_name",title="自动化用例测试报告",description="登陆测试用例")
runnner.run(s)
from BeautifulReport import BeautifulReport
br = BeautifulReport(s)
br.report("登陆",filename="Beautiful_Report",report_dir='.')
这里我导入了OS库,查看当前文件路径,当然,大家可以直接右键Copy Path 然后使用discover方法将用例收集到TestSuite测试套件中, 这里会从项目目录下说搜索所有测试用例,并加载到测试套件中 1、指定搜索目录 2、文件过滤规则:以文件名匹配。test*.py 3、在文件中过滤用例:继承了unittest.TestCase类的测试类,类当中以 test_ 开头的测试函数
unittest.TestLoader().discover(fs)
随后就可以导入HTMLTestRunner方法,添加一些报告信息,然后调用测试套件 执行用例 + 生成报告: HTMLTestRunner from HTMLTestRunner import HTMLTestRunner runner = HTMLTestRunner(output=".", report_name=“report_name”) runnner.run(测试套件变量名)
from HTMLTestRunner import HTMLTestRunner
runnner = HTMLTestRunner(output=".", report_name="report_name",title="自动化用例测试报告",description="登陆测试用例")
runnner.run(s)
还有第二种方法BeautifulReport BeautifulReport from BeautifulReport import BeautifulReport # 实例化 br = BeautifulReport(测试套件变量名) br.report(description,report_dir=’.’)d
from BeautifulReport import BeautifulReport
br = BeautifulReport(s)
br.report("登陆",filename="Beautiful_Report",report_dir='.')
|