python自动化测试—unittest框架四大核心概念学习
unittest框架最核心的四个概念:
一、unittest中测试用例的编写规范
在测试类当中,以test_开头,定义测试函数
每一个test_开头的函数,就是一个测试用例
用例编写步骤:
1 导入unittest模块,被测文件或者其中的类
2 创建一个测试类,并继承unittest模块中的TestCase类
3 定义测试函数,函数名以test_开头(一个test开头的方法就是一条测试用例)
4 将测试用例执行的代码逻辑写到对应的测试方法中:
第一步:准备用例数据
第二步: 调用被测的功能函数(发送请求调用接口),获取实际结果
第三步: 断言,预期结果与实际结果的对比
下面编写测试登陆功能的测试用例:
登录的功能逻辑定义在login模块里
import unittest # 引入 unittest
from python01.python02.login import login_check # 导入login模块的登录函数
class TestLogin(unittest.TestCase): # 定义测试类,继承unittest.TestCase
def test_login_ok(self): # 用例1
# 第一步:准备用例数据
params = {'username': "cyy", "password": 123456}
expected = {"code":0,"msg":"登录成功"}
# 第二步:调用被测的功能函数(发送请求调用接口),获取实际结果
result = login_check(**params)
# 第三步:断言
self.assertEqual(result, expected)
上述只是执行了一条用例,下面再看下五条用例的:
用例1 账号密码正确
入参:账号cyy,密码:123456
预期结果:{“code”:0,“msg”:“登录成功”}
实际结果:
用例2 账号正确,密码错误
入参:账号cyy,密码:fdgg
预期结果:{“code”:1,“msg”:“账号或密码不正确”}
实际结果:
用例3 账号错误,密码正确
入参:账号cyy1,密码:123456
预期结果:{“code”:1,“msg”:“账号或密码不正确”}
实际结果:
用例4 账号为空
入参:账号,密码:123456
预期结果:{“code”:1,“msg”:“所有的参数不能为空”}
实际结果:
用例5 密码为空
入参:账号cyy,密码:
预期结果:{“code”:1,“msg”:“所有的参数不能为空”}
实际结果:
import unittest # 引入 unittest
from python01.python02.login import login_check # 导入login模块的登录函数
class TestLogin(unittest.TestCase): # 定义测试类,继承unittest.TestCase
def test_login_ok(self): # 用例1
# 第一步:准备用例数据
params = {'username': "cyy", "password": 123456}
expected = {"code":0,"msg":"登录成功"}
# 第二步:调用被测的功能函数(发送请求调用接口),获取实际结果
result = login_check(**params)
# 第三步:断言
self.assertEqual(result, expected)
def test_login_password_wrong(self): # 用例2
params = {'username': "cyy", "password": "fdgg"}
expected = {"code": 1, "msg": "账号或密码不正确"}
result = login_check(**params)
self.assertEqual(result, expected)
def test_login_user_wrong(self): # 用例3
params = {'username': "cyy1", "password": 123456}
expected = {"code": 1, "msg": "账号或密码不正确"}
result = login_check(**params)
self.assertEqual(result, expected)
def test_login_no_user(self): # 用例4
params = {'username': None, "password": 123456}
expected = {"code": 1, "msg": "所有的参数不能为空"}
result = login_check(**params)
self.assertEqual(result, expected)
def test_login_no_password(self): # 用例5
params = {'username': "cyy", "password": None}
expected = {"code": 1, "msg": "所有的参数不能为空"}
result = login_check(**params)
self.assertEqual(result, expected)
# 以上代码存于 test_case_01.py模块
执行结果:
这里要注意,每个用例之间都是互相独立,如果其中一个用例报错了,不会影响其他用例的执行。
其中,我们断言用到的是assertEqual(a,b),作用是判断a和b是否相等,如果不相等则断言失败,报错AssertionError,而AssertionError是unittest框架识别用例失败的标识之一
另外unittest还有很多常用的断言方法如下:
二、收集用例TestSuite(测试套件),TestLoader加载用例
import unittest
# 1、创建套件
s = unittest.TestSuite()
# 2、创建一个用例加载器,并加载测试用例到套件(一般用TestLoader加载用例(收集用例))
s = unittest.TestLoader().discover("D:\pythoncharm01\python01")
print(type(s))# 打印出是一个TestSuite类(把发现的测试用例丢到TestSuite类里面)
# 以上代码存于 run.py模块,与test_case_01.py模块同级目录
unittest.TestLoader().discover(搜索目录),搜索用例的方式:discover
从start_directory这个目录下开始,搜索所有的测试用例,并加载到测试套件中。遵循以下原则:
1、指定搜索目录
2、文件过滤规则:以文件名匹配(test*.py),以test开头,.py结尾
3、在文件当中过滤用例:继承了unittest.TestCase类的测试类,类当中以test_开头的测试函数。
这种方式方便以后的更改,因为是从目录中获取的
还有其他的用例收集方法,例如:
实例化测试套件TestSuite
s = unittest.TestSuite()
1 添加一个用例 addTest(类名(”用例名“))
s.addTest()
2 添加多个用例 addTest(类名(”用例名1“),类名(”用例名2“),类名(”用例名3“))
s.addTests()
3 TestLoader还可以通过类名、模块名,方式去收集用例
这些收集用例方法比较费劲一般不用,了解即可。
三、执行用例+测试报告
为了验证第二点收集用例功能,同级目下再创建一个测试用例模块(定义了两条用例,一条是错的),看执行用例时是否会和test_case_01.py模块的用例一起加载出来
接下来我们要运行测试用例,并生成结果
这里我们用一个今年7月份发布的一个资源包unittestreport,关于它的详细介绍可以到PYPI了解
安装:pip install unittestreport
import unittest
# 1、创建套件
s = unittest.TestSuite()
# 2、创建一个用例加载器,并加载测试用例到套件(一般用TestLoader加载用例(收集用例))
s = unittest.TestLoader().discover("D:\pythoncharm01\python01")
##########################################################################
from unittestreport import TestRunner #从unittestreport中导入TestRunner类
#先实例化TestRunner,
runner = TestRunner(s,filename = "python01.html",tester='小菜',desc="小菜项目测试报告")
# 再执行用例,生成报告
runner.run()
#以上代码存于 run.py模块
关于括号里面填写的参数意思,可以进入源码进行查看:
执行后,生成如下测试报告:
一共7条用例,其中5条是test_case_01.py模块的,还有两条是test_case_02.py模块的
再介绍一个方法,这种方式生成的报告也还不错
#安装:pip install BeautifulReport
from BeautifulReport import BeautifulReport
br = BeautifulReport(s)
br.report("12月1号测试报告","python02.html")
## 都是一样的套路:先实例化,再运行用例,生成html报告
再扩展个可以减少代码的写法
四、前置后置条件fixture
有时候会遇到一些特殊情况,如果要在用例执行前做一些环境的准备工作,在用例执行后做一些清理工作该怎么办?
这就涉及到我们编写用例用到的前置后置(fixture),就是平常我们功能用例编写用到的前置/后置条件(可有可无)
1 setUp(前置条件),tearDown(后置条件) -类下面的每一个用例在执行之前,会执行setUp, 在每一个用例执行之后,会执行teardown。
import unittest
from python01.python02.login import login_check
class TestLogin(unittest.TestCase):
def setUp(self) -> None:
print('前置条件')
def tearDown(self) -> None:
print("后置条件")
def test_login_ok(self): # 用例1
res = login_check("cyy", 123456)
self.assertEqual(res, {"code": 0, "msg": "登录成功"})
def test_login_password_wrong(self): # 用例2
res = login_check("cyy", 789465)
self.assertEqual(res, {"code": 1, "msg": "账号或密码不正确"})
执行如下:
Ran 2 tests in 0.002s
OK
前置条件
后置条件
前置条件
后置条件
2 setUpClass,tearDownClass,类里面的第一个用例执行之前会执行setUpClass,类里面的最后一个用例执行之后才执行tearDownClass
import unittest
from python01.python02.login import login_check
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print("前置条件")
@classmethod
def tearDownClass(cls) -> None:
print("后置条件")
def test_login_ok(self): # 用例1
res = login_check("cyy", 123456)
self.assertEqual(res, {"code": 0, "msg": "登录成功"})
def test_login_password_wrong(self): # 用例2
res = login_check("cyy", 789465)
self.assertEqual(res, {"code": 1, "msg": "账号或密码不正确"})
执行结果如下:
Ran 2 tests in 0.001s
OK
前置条件
后置条件
以上unittest框架四大核心概念介绍完毕,接下来,再介绍点其他知识
五、用例执行顺序:ASCII码
ASCII吗的大小规则:0-9<A-Z<a-z
例如文件名,test_c.py和test_a.py,就会先执行test_a.py模块
然后进入到文件内部,测试用例执行的顺序也是识别每个函数名,从函数名不同的地方开始识别
若想自己指定顺序,在文件名或者用例名称上做改动
六、ddt数据驱动测试 data driven test
假如有一个测试流程是不变的,针对这个流程设计了几十条测试用例(流程不变,变的是测试数据),就可以用ddt数据驱动模块。数据驱动思想。
注意:由于现在好多人理解的数据驱动思想不一致,所以我们不能说特别掌握,只能说这个场景可以用数据驱动思想去实现。
首先要安装 pip install ddt
1、引入ddt-------import ddt
2、在测试类名的上面,用@ddt.ddt,
3、在测试函数上面,用@ddt.data(*列表)
4、在测试函数的参数中,定义一个参数用来接收每一组测试数据
import unittest # 引入 unittest
from python01.python02.login import login_check # 导入login模块的登录函数
datas = [{"username": "cyy", "password": 123456, "check": {"code": 0, "msg": "登录成功"}},
{"username": "cyy", "password": 12345, "check": {"code": 1, "msg": "账号或密码不正确"}},
{"username": "cy", "password": 123456, "check": {"code": 1, "msg": "账号或密码不正确"}},
{"username": None, "password": 123456, "check": {"code": 1, "msg": "所有的参数不能为空"}},
{"username": "cyy", "password": None, "check": {"code": 1, "msg": "所有的参数不能为空"}},
]
import ddt #导入ddt
@ddt.ddt # 在测试类名的上面,用@ddt.ddt
class TestLogin(unittest.TestCase):
@ddt.data(*datas) #在测试函数上面,用@ddt.data(*列表) #拆包后将多组测试数据依次传递给一个测试流程
def test_login_ok(self, case): #在测试函数的参数中,定义一个case参数用来接收每一组测试数据
result = login_check(case["username"], case["password"])
self.assertEqual(result, case["check"])
这就是数据驱动测试,就可不用每条数据写一条用例了
本文地址:https://blog.csdn.net/cai217/article/details/110356685
推荐阅读
-
Python+Selenium+Unittest+Ddt+HTMLReport分布式数据驱动自动化测试框架结构
-
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
-
Python+unittest+requests+excel实现接口自动化测试框架
-
python自动化测试—unittest框架四大核心概念学习
-
Python Unittest自动化单元测试框架详解
-
Python+Selenium+Unittest+Ddt+HTMLReport分布式数据驱动自动化测试框架结构
-
Python+unittest+requests+HTMLTestRunner完整的接口自动化测试框架搭建_07——HTMLTestRunner
-
python+selenium自动化测试-22python单元测试框架unittest(原理详解)
-
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
-
Python Unittest自动化单元测试框架详解