tags: [“pytest”, “python”]
快速上手Pytest接口测试
背景
以前有分享过httprunner+pytest相关的使用方法,并且一直使用httprunner编写用自动化脚本,以前的经验可以快速帮我们上手pytest框架。为了快速上手pytest,HttpRunner 与Pytest 在编写自动化脚本异同点对比:
项目初始化
克隆项目◦ git clone git@gitlab.guangpuyun.cn:clinic-diag/test/poct_api_test.git 了解项目结构
安装依赖
◦ 项目根目录下打开终端,执行pip install -r requirements.txt
测试用例格式
- 用例文件以test_开头或_test结尾◦ 建议以场景命名-如四合一的快速检测:test_zk_quicktest.py
- 用例集合——类,以Test开头(可以无)◦ 包含1个或多个测试用例函数
- 测试用例函数以test_开头◦ 一个函数代表一条用例- $_->$ 一个明确的测试点
用例转换
1、运行脚本utils/swaager.py——爬取swagger文档资源,存放于/api/swaggerApi目录 2、运行脚本api/generateTestCases.py,生成基础用例,存放于/api目录 3、基础用例结构
此时只是生成了接口的对象,还需要编写实现逻辑和传参进一步实现该对象,完成测试用例编写(见用例编写)
用例编写
- 在/test对应的目录下新建用例文件,命名以test_开头,表明测试场景
- 导入必要的包和基础用例,如:
from utils.logger import loggerfrom api.poctMina.addcartusingPosT import YsbMallCartController
3. 编写测试用例
from utils.logger import logger fron api.poctMina.addCartUsinqPosT import YsbMallCartController def test_addCartUsing(getTokenBySecret,pytestconfig): 用例名称-体现在报告上 addCartUsing $\mathbf{\sigma}=\mathbf{\sigma}$ YsbHallCartController ( addcartUsing.base_url $\mathbf{\sigma}=\mathbf{\sigma}$ pytestconfig.getini(‘poct-host’) 构造url addCartUsinq.data[‘addNum’]=1 addCartUsing.data[‘packageId’] $=2\dot{0}\dot{\Theta}$ addCartUsing.data[*token’]=getTokenBySecret(store=3o15659) 构造传参 response_data=addcartUsing.addcart() .json() 获取返回值 logger.info(response_data) assert response_data[‘code’] $\scriptstyle==$ ‘40001’ 断言
用例参数化
1. 直接传参给函数 (小数据量)
@pytest.mark.parametrize(x,y,[(x1,y1),(x2’,y2’)],indirect=True)
2. 当需要对参数进行处理时
@pytest.fixture(scope=‘class’,autouse $\risingdotseq$ True, params $\c=$ order_id,ids $\c=$ ids)scope作用域-可以是function,class,module,session;配合@pytest.mark.parametrize(x,[1,2],indirect $\varXi^{-}$ True)传参使用, #indirect $\varXi^{-}$ True代表使用fixture函数处理数据。 request.param 在 fixture 中获取原始参数值。
1 import pytest 2 3 @pytest.fixture 4 def number(request): 5 return request.param $\star$ 2 6 7 @pytest.mark.parametrize(“number”, [1, 2, 3], indirect=True) 8 def test_number(number): 9 assert number in [2, 4, 6]
3. 参数化从文件读取数据
从外部文件(如 CSV、JSON、YAML)读取测试数据,适用于数据量较大或需要动态生成数据的场景。
1 import pytest 2 import json 3 4 def load_test_data(file_path): 5 with open(file_path, $“r”$ ) as f: 6 return json.load(f) 7 8 @pytest.mark.parametrize(“test_case”, load_test_data(’test_data.json’)) 9 def test_from_file(test_case): 10 assert test_case[‘input’] $^+$ test_case[‘addend’] $\scriptstyle==$ test_case[’expected’]
pytest_generate_tests 钩子函数来自定义参数化。
在测试收集阶段动态生成参数。 适用于需要在多个测试函数中共享参数化逻辑的情况。
1 def pytest_generate_tests(metafunc): 2 if “num” in metafunc.fixturenames: 3 numbers $\mathbf{\Psi}=\mathbf{\Psi}$ [1, 2, 3] 4 metafunc.parametrize(“num”, numbers) 5 def test_number(num): 6 assert num in [1, 2, 3]
5. 用例参数化 Fixture
参数化 fixture,使其在不同的测试中提供不同的数据。
1 import pytest 2 @pytest.fixture(params $\c=$ [1, 2, 3]) 3 def number(request): 4 return request.param 5 def test_number(number): 6 assert isinstance(number, int)
用例封装
1. fixture关键字驱动
方法:
通过@pytest.fixture装饰器封装一些常用的工具函数放到conftest.py作用:
a. 用例中可实现不用导包直接使用。b. 可实现用例之间的参数传递c. 可作用于全局,也可灵活定义作用域
例如:conftest.py中定义fixture函数获取token
在用例中直接使用getTokenBySecret函数获取token:
2. 公用模块的封装
存放一些封装好的可复用的公共模块,如连接数据库,reques请求,日志模块等
用例断言
a. 判断是否为真: assert xxb. 判断不为真: assert not xxc. 判断a是否包含b: assert a in bd. 判断a不包含b: assert a not in be. 判断两值相等: assert b $\mathtt{\Gamma}==\mathtt{a}$ f. 判断两值不相等: assert a != b
运行
1. 终端
◦ pytest -q/-s 静默运行/运行时显示打印 ◦ 运行结果生成报告 pytest –html=report.html ◦ 运行指定用例 pytest test_se.py::TestClassone::test_one ◦ 多进程数(NUM)运行 pytest test_se.py -n NUM ◦ 运行失败重试(NUM)次:pytest test_se.py –reruns NUM ◦ 跳过用例运行@pytest.mark.skip ◦ 重试@pytest.mark.flaky(reruns $^{:=3}$ , reruns_delay $^{\prime=2}$ ) #失败时重试3次,每次间隔2秒
2. 代码运行
直接运行main.py(提交代码前必须运行通过)
测试报告
浏览器打开pytest_report.html
光谱接口自动化测试报告
Report generated on 12-Mar-2025 at 16:13:25 by pytest-html v4.1.1
Environment
summary
17 tests took 00:01:11
(Un)check the boxes to filter the results
说些什么吧!