当前位置: 首页 > news >正文

6:参数化

承接前两篇:Pytest 用例规则 + 前后置 + 原生 assert 断言,本篇讲解参数化,接口自动化核心必备。日常接口需要覆盖正常、异常、边界多组入参,参数化实现「一套用例代码,多组数据循环执行」,大幅减少重复代码。

一、什么是参数化,为什么自动化必须用?

1. 概念

@pytest.mark.parametrize是 pytest 内置装饰器,批量传入多组测试数据,自动循环生成多条独立测试用例,一组数据对应 1 次用例执行。

2. 解决痛点

不使用参数化:多组入参就要复制多份测试函数,代码冗余、后期维护困难; 使用参数化:只写 1 次用例逻辑,数据源统一维护,新增 / 删减数据不用改动业务代码,接口边界、异常场景全覆盖。

接口测试场景:登录接口(正确账号、密码为空、错误密码、手机号格式错误)4 种场景,参数化 1 行配置 4 组数据即可。

二、基础语法格式

@pytest.mark.parametrize(参数名字符串, 数据集列表) def test_xxx(参数名): # 测试逻辑+断言
  • 第一个入参:"参数1,参数2"多个参数用英文逗号分隔;
  • 第二个入参:嵌套列表 / 元组,每组元素一一对应前面的参数。

三、四种常用参数化写法(从单参数→类→全局→自定义数据源)

写法 1:函数级别参数化(单 / 多参数,项目最常用)

① 多参数传参(示例:计算器表达式校验,文档原示例优化)
import pytest # 参数1:计算公式字符串,参数2:预期结果 @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)]) def test_eval(test_input, expected): # 执行计算公式 res = eval(test_input) # 结合上篇断言知识点 assert res == expected, f"公式{test_input}预期{expected},实际{res}"

执行pytest -vs,自动生成3 条独立用例,其中6*9=54≠42会单独失败,精准定位出错数据。

② 单参数简易示例
@pytest.mark.parametrize("phone",["13800138000","","123456"]) def test_phone_format(phone): # 校验手机号长度 assert len(phone)==11,f"手机号{phone}长度非法"

写法 2:测试类上参数化(类内所有 test 方法共用一套数据源)

装饰器写在 class 上方,类中全部以 test 开头的方法自动继承参数,每组数据所有方法循环执行一遍

import pytest # 两个参数 n:入参数字,expected:预期结果 @pytest.mark.parametrize("n,expected", [(1, 2), (3, 4)]) class TestClass: def test_simple_case(self, n, expected): assert n + 1 == expected def test_weird_simple_case(self, n, expected): assert (n * 1) + 1 == expected

执行结果:2 组数据 × 2 个用例 = 总共 4 条测试用例。

写法 3:模块全局参数化(当前 py 文件全部用例统一数据)

在脚本顶部定义全局变量pytestmark,本文件所有测试类、测试函数自动复用参数,不用逐个加装饰器

import pytest # 全局参数配置,本模块所有用例自动带入n、expected参数 pytestmark = pytest.mark.parametrize("n,expected", [(1, 2), (3, 4)]) class TestClass: def test_simple_case(self, n, expected): assert n + 1 == expected def test_weird_simple_case(self, n, expected): assert (n * 1) + 1 == expected # 类外函数同样自动参数化 def test_global_demo(n,expected): assert n+1 == expected

写法 4:自定义函数返回数据源(数据和代码分离,实战优选)

把测试数据单独封装函数,后续拓展:从 json/yaml/excel 读取用例数据,实现数据代码完全分离

import pytest # 自定义数据源函数,后续可改成读取文件 def data_provider(): return ["a", "b"] # 直接传入函数名,自动读取返回列表 @pytest.mark.parametrize("data", data_provider()) def test_data(data): assert data is not None print(f"Testing with data provider: {data}")

拓展:企业项目中data_provider()内部写读取 yaml 接口用例,是主流接口自动化方案。

四、接口自动化实战案例(落地场景,结合 requests + 断言)

import pytest import requests # 接口参数:帖子id,预期用户id @pytest.mark.parametrize("post_id,expect_uid",[(1,1),(2,2),(99,99)]) def test_post_api(post_id,expect_uid): url = f"https://jsonplaceholder.typicode.com/posts/{post_id}" res = requests.get(url) # 断言状态码 assert res.status_code == 200,f"接口{url}请求异常" json_data = res.json() # 校验返回用户id assert json_data["userId"] == expect_uid,f"帖子{post_id}预期用户{expect_uid},实际{json_data['userId']}"

执行后 3 个接口分别发起请求,任意一组数据出错单独标记失败,不影响其他用例执行。

五、进阶实用小技巧

1. 给每组用例自定义用例名称(ids 参数)

默认用例名是参数内容,可读性差,通过ids给每组数据起名,报告清晰

@pytest.mark.parametrize("user,pwd",[("admin","123456"),("admin","")],ids=["正常登录","密码空登录"]) def test_login(user,pwd): pass

执行日志直接显示:test_login[正常登录]test_login[密码空登录]

2. 跳过指定参数用例(pytest.mark.skipif)

部分测试数据临时不需要执行,动态跳过单组用例

data = [(1,2),(3,4)] @pytest.mark.parametrize("n,e",data) def test_skip(n,e): if n ==3: pytest.skip("该场景暂未开发完成,临时跳过") assert n+1 ==e

六、常见踩坑总结

  1. 参数数量匹配:参数名几个,每组元组必须对应相同元素,否则直接报参数不匹配报错;
  2. 全局 pytestmark 优先级:函数单独写了 parametrize 会覆盖全局配置;
  3. 数据分离规范:项目用例多了不要把数据硬编码写在装饰器里,统一放到函数 / 配置文件。
http://www.gsyq.cn/news/1450206.html

相关文章:

  • 从‘韩信点兵’到‘中国剩余定理’:一个Python循环带你入门数论算法
  • 广州CMA甲醛检测治理公司深度测评:绿居净环保稳居榜首 - 金诚回收
  • 守护风电场 “无线神经”:LN-090A 宽频高速手持式频谱分析仪
  • 自然语言驱动的无代码AI应用生成平台选型指南
  • 【限时解密】某千亿级电商平台AI中台架构图(脱敏版):含实时特征管道、模型AB分流网关、合规审计埋点设计
  • 解放你的音乐收藏:零依赖本地批量qmcflac转mp3全攻略
  • 科学图像分析终极指南:用ImageJ快速处理显微图像数据
  • 东莞本地正规黄金回收店排行 实测资质与服务对比 - 互联网科技品牌测评
  • 2026年中国分户供暖市场能效演进与全预混冷凝技术样本观察
  • 贵港CMA甲醛检测治理公司深度测评:绿居净环保稳居榜首 - 金诚回收
  • 衡阳母婴除甲醛CMA甲醛检测治理公司2026深度测评:森氧家环保稳居榜首 - 五金回收
  • IT 圈大实话!卷运维不如卷网络安全(2026 转行必看)
  • 人像抠图用什么工具?2026免费+专业方案教程
  • 解密macOS数据库管理:开源工具链实战指南
  • 晋中母婴除甲醛CMA甲醛检测治理公司2026深度测评:森氧家环保稳居榜首 - 五金回收
  • 2026年视频转文字完全教程|手把手教你快速提取视频文字
  • 超越端到端:为什么模块化‘建图+规划’在机器人目标导航中又火了?——以SemExp为例
  • 新手站长必看:用Nginx搞定域名301重定向,顺便给个人网站穿上EdgeOne的‘防弹衣’
  • 六位半万用表选购避坑指南:从RIGOL DM3068与Fluke 45的实测对比,聊聊高精度测量的那些‘暗坑’
  • 蚌埠CMA甲醛检测治理公司深度测评:绿居净环保稳居榜首 - 金诚回收
  • 蚌埠母婴除甲醛CMA甲醛检测治理公司2026深度测评:森氧家环保稳居榜首 - 金诚回收
  • 保姆级教程:用QGIS和NASA免费数据,5步搞定专业地形图(附SRTM-Downloader插件配置)
  • 告别手动数细胞:用DETR+特征融合,5步搞定白细胞自动检测(附代码)
  • Lindy供应链自动化实战白皮书(2024企业级避坑图谱)
  • 包头母婴除甲醛CMA甲醛检测治理公司2026深度测评:森氧家环保稳居榜首 - 金诚回收
  • 别再一断了之!用C#优雅清理Socket Receive缓存区的3种姿势
  • 告别硬件SPI引脚冲突!STM32F103 HAL库下GPIO软件模拟SPI驱动MAX31865的完整指南
  • 如何利用QRemeshify解决Blender中复杂网格的四边形重拓扑难题
  • 从CAD图纸到SW三维模型:手把手教你完成轮式割草机器人的结构设计与装配
  • DC-DC降压转换器实战:利用废电池驱动LED灯,实现宽电压电源管理