接口自动化测试:一文搞懂 Pytest 自动化测试框架
目录
一、什么是 pytest
Pytest 是一个基于 Python 的开源测试框架,对于接口自动化测试来说,可以自动识别到测试用例,不需要再动手编写 main 函数并调用测试用例
安装命令:
pip install pytest
安装成功按运⾏规则使用会出现 绿色的三角形 标志
二、为什么测试需要 pytest
不知道你是否和我一样有疑惑,刚开始学习 Python 自动化测试时,我有一个疑问:
Python 文件直接运行就能得到结果,为什么还需要学习 Pytest?
例如下面这段代码:
def add(a, b):
return a + b
print(add(1, 2))
直接运行:
3
程序正常执行,结果也正确。
既然 Python 已经能够运行代码,那为什么自动化测试项目几乎都在使用 Pytest 呢?
直接运行 Python 代码存在哪些问题
实际上,当项目规模变大后,仅仅依靠 print() 或手动运行代码已经无法满足测试需求。
问题1:无法自动判断结果是否正确
例如:
def add(a, b):
return a + b
print(add(1, 2))
控制台输出:
3
程序确实运行成功了。
但是:
- 谁来判断结果是否正确?
- 是人工查看吗?
- 如果有1000个测试场景怎么办?
问题2:无法批量执行测试
假设有100个功能:
- 登录
- 注册
- 修改密码
- 上传头像
- 搜索商品
- 提交订单 …
如果每个功能都单独运行:
python login.py
python register.py
python order.py
效率非常低。
而测试框架可以一次执行全部测试:
pytest
自动发现并运行所有测试用例。
问题3:无法生成测试报告
当项目拥有几百条测试用例时,开发和测试最关心的是:
- 通过多少条?
- 失败多少条?
- 哪些功能失败了?
- 错误原因是什么?
如果只依靠 Python 运行:
print("执行成功")
很难统计测试结果。
而 Pytest 可以自动输出:
def test_03():
json = {
"name":"hr",
"age":110
}
json_schema = {
"type": "object",
"properties": {
"name": {
"type": "string",
},
"age": {
"type": "integer",
"exclusiveMinimum":0,
"exclusiveMaximum":100
}
},
"required": [
"name",
"age"
]
}
validate(instance=json,schema=json_schema)
def test_04():
json = {
"name":"hrrrrr",
"age":10
}
json_schema = {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern":"\S{2,5}"
},
"age": {
"type": "integer",
}
},
"required": [
"name",
"age"
]
}
validate(instance=json,schema=json_schema)
控制台输出:

具体到哪个位置哪个部分出现了哪些问题,甚至生成 HTML、Allure 测试报告。
问题4:无法管理测试数据
例如登录测试:
admin / 123456
test / 888888
guest / 666666
如果使用普通 Python:
test_login_admin()
test_login_test()
test_login_guest()
会出现大量重复代码。
Pytest 支持参数化:
@pytest.mark.parametrize(
"username,password",
[
("admin","123456"),
("test","888888"),
("guest","666666")
]
)
一套代码即可执行多组数据。
问题5:无法统一管理测试环境
在实际项目中,经常需要:
- 登录系统
- 创建测试数据
- 连接数据库
- 初始化浏览器
- 清理测试环境
如果每个测试都重复编写:
login()
connect_db()
open_browser()
维护成本极高。
Pytest 的 Fixture 机制可以统一管理这些公共操作。
三、Pytest 的基本使用
1. 编写第一个测试用例
判定两数之和是否大于3 :
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
执行测试,在命令行中输入:
pytest

执行结果(需要添加命令参数):

2. 命名规则
既然执行测试需要在命令行输入,那 pytest 是怎么知道我们是要测试哪一个呢,其实这就跟⽤例命名规则有关系了,并不是所有的⽅法都可以直接运⾏
Pytest 默认识别以下规则:
- 文件名必须以
test_开头或者_test结尾 - 测试类必须以
Test开头,并且不能有__init__方法。 - 测试方法必须以
test开头
方法名
def test02_01():
print("test02_01")
def test02_02():
print("test02_02")
def test02_03():
print("test02_03")
文件名

# 文件名为 test_02.py
def test02_01():
print("test02_01")
def test02_02():
print("test02_02")
def test02_03():
print("test02_03")
类名
class Test02():
def test02_01(self):
print("test02_01")
def test02_02(self):
print("test02_02")
def test02_03(self):
print("-test02_03")
注意!!:Python类中不可以添加 init⽅法

由于 pytest 的测试收集机制,测试类中不可以定义_ _init_ _方法。pytest 采用自动发现机制来收集测试用例。它会自动实例化测试类并调用其所有以test结尾的方法作为测试用例。如果测试类中定义了__init__方法,那么当pytest实例化该类时,__init__方法会被调用,这可能会掩盖测试类的实际测试逻辑,并引入额外的副作用,影响测试结果的准确性。
为了避免使用
_init__方法,建议在pytest中使用其他替代方案,如使用setUp()和tearDown()方法、使用类属性、使用fixture函数
3. pytest命令参数
在实际项目中,我们很少直接使用:pytest
因为不能直接看到接口请求日志、入参出参等信息
举个例子:
def add(a, b):
return a + b
def test_add():
print(add(1, 2))
直接使用:
pytest
执行结果:
就只能看到用例是否执行成功
如果使用参数 -sv:
pytest -sv
执行结果:
既能输出具体的测试用例名称,还能输出print语句
pytest 常见命令行参数
我们可以结合不同参数完成指定场景的测试执行,以下是一些常用的pytest 命令行参数及其使用说明
| 命令 | 描述 | 备注 |
|---|---|---|
pytest |
自动搜索当前目录及子目录下的测试用例并执行 | 最常用 |
pytest -v |
显示更详细的测试执行信息 | verbose(详细模式) |
pytest -s |
显示测试中的 print() 输出 |
调试时常用 |
pytest -vs |
同时显示详细信息和打印输出 | 实际工作中最常用 |
pytest test_module.py |
执行指定测试文件 | 指定模块运行 |
pytest test_dir/ |
执行指定目录下的所有测试 | 批量执行 |
pytest test_module.py::test_func |
执行指定测试函数 | 精准定位测试 |
pytest test_module.py::TestClass |
执行指定测试类 | 常用于调试 |
pytest -k <keyword> |
执行名称包含指定关键字的测试 | 模糊匹配 |
pytest -m <marker> |
执行指定标记的测试 | 需提前定义 Marker |
pytest -q |
简化输出信息 | quiet(静默模式) |
pytest -x |
遇到第一个失败立即停止 | 冒烟测试常用 |
pytest --lf |
仅执行上次失败的测试用例 | Last Failed |
pytest --ff |
优先执行上次失败的测试用例 | Failed First |
pytest --pdb |
测试失败后进入调试模式 | 类似断点调试 |
pytest --maxfail=2 |
最多失败 2 次后停止执行 | 控制失败次数 |
pytest --html=report.html |
生成 HTML 测试报告 | 需安装 pytest-html |
pytest --cov |
统计测试覆盖率 | 需安装 pytest-cov |
pytest --cov=app |
统计指定目录覆盖率 | 推荐使用 |
pytest -n 4 |
使用 4 个进程并发执行 | 需安装 pytest-xdist |
pytest --reruns 3 |
失败后自动重试 3 次 | 需安装 pytest-rerunfailures |
pytest --collect-only |
仅收集测试用例,不执行 | 查看测试发现结果 |
4. pytest配置⽂件(pytest.ini)
随着项目规模增大,如果每次执行测试都需要输入大量命令参数
例如:
pytest -vs -m smoke --html=report.html
又臭又长,不仅麻烦,而且团队成员之间执行方式可能不一致。
因此 Pytest 提供了配置文件机制,可以将常用配置统一管理
我们需要创建 pytest.ini 文件,通常把它放在项目根目录
pytest.ini 常用配置项
| 配置项 | 作用说明 |
|---|---|
addopts |
指定默认执行参数,等同于每次运行 pytest 时自动追加这些命令行参数 |
testpaths |
指定测试用例搜索目录 |
python_files |
指定测试文件匹配规则 |
python_classes |
指定测试类匹配规则 |
python_functions |
指定测试函数或测试方法匹配规则 |
norecursedirs |
指定搜索测试时需要忽略的目录 |
markers |
注册测试标记(Marker),用于分类执行测试用例 |
示例:详细输出 testcase 包下文件名以 test_ 开头且方法以 Test 开头 的所有用例
project
│
├── testcase
│ └── test_login.py
│
└── pytest.ini
[pytest]
addopts = -vs
; 指定搜索测试的目录
testpaths = ./testcase
; 指定文件名,即使他不是在规则命名
python_files = test_*.py
; 指定类名,即使他不是在规则命名
python_classes = Test*
; 指定方法名,即使他不是在规则命名
python_functions = test_*
class TestLogin:
def test_login_success(self):
print("登录成功")
def test_login_fail(self):
print("登录失败")
配置好 pytest.ini ⽂件后,命令⾏执⾏ pytest 命令即可,⽆需再额外指定其他参数:
5. 前后置
在命名规则的章节,我挖了一个坑,既然不能测试类
__init__方法,那该如何进⾏数据的初始化?
在测试框架中,前后置 是指在执⾏测试⽤例前和测试⽤例后执⾏⼀些额外的操作,这些操作可以⽤于设置测试环境、准备测试数据等,以确保测试的可靠性
pytest 框架提供三种方法做前后置的操作:
setup_method和teardown_method:这两个方法用于类中的每个测试方法的前置和后置操作。setup_class和teardown_class:这两个方法用于整个测试类的前置和后置操作。fixture:这是 pytest 推荐的方式来实现测试用例的前置和后置操作。fixture 提供了更灵活的控制和更强大的功能。
setup_method 和 teardown_method
作用:
- 每个测试方法执行前运行一次
setup_method - 每个测试方法执行后运行一次
teardown_method
示例:
class TestLogin:
def setup_method(self):
print("登录系统")
def teardown_method(self):
print("退出系统")
def test_order(self):
print("提交订单")
def test_pay(self):
print("订单支付")
执行结果:

setup_method
↓
测试方法
↓
teardown_method
setup_class 和 teardown_class
作用:
- 整个测试类执行前运行一次
setup_class - 整个测试类执行后运行一次
teardown_class
示例:
class TestLogin:
def setup_class(self):
print("启动浏览器")
def teardown_class(self):
print("关闭浏览器")
def test_order(self):
print("提交订单")
def test_pay(self):
print("订单支付")
执行结果:
setup_class
↓
所有测试方法
↓
teardown_class
6. 断言机制(Assert)
Pytest 使用 Python 原生 assert 进行断言,用于验证实际结果与预期结果是否一致
基本语法:
assert 条件, 错误信息
• 条件:必须是⼀个布尔表达式
• 错误信息:当条件为假时显⽰的错误信息,可选
示例:
import pytest
import requests
# ====================== 基础数据类型断言示例 ======================
def test_base():
"""整数、字符串断言"""
# 整数断言
a = 1
b = 1
assert a == b
# 字符串断言(此处两个字符串不一致,运行会失败)
str1 = "hello"
str2 = "hello world"
assert str1 == str2
def test_ds():
"""列表、元组、字典容器类型断言"""
# 列表断言
expect_list = [1, 'hello', 3.14]
actual_list = [1, 'hello', 3.14]
assert expect_list == actual_list
# 元组断言
expect_tuple = (1, 'hello', 3.14)
actual_tuple = (1, 'hello', 3.14)
assert expect_tuple == actual_tuple
# 字典断言
expect_dict = {'name': 'hr', 'age': 25}
actual_dict = {'name': 'hr', 'age': 25}
assert expect_dict == actual_dict
def divide(a, b):
"""除法工具函数:除数非0断言"""
assert b != 0, "除数不能为0"
return a / b
def test_divide():
"""函数返回值断言、异常场景断言"""
# 正常除法
print(divide(10, 2))
# 除数为0触发断言报错
print(divide(10, 0))
# ====================== 接口自动化断言示例 ======================
def test_api01():
"""全量校验接口返回JSON完整数据"""
url = "https://jsonplaceholder.typicode.com/posts/1"
r = requests.get(url=url)
actual_data = r.json()
expect_data = {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
assert expect_data == actual_data
def test_api02():
"""只校验JSON返回结果中的单个关键字段"""
url = "https://jsonplaceholder.typicode.com/posts/1/comments"
r = requests.get(url=url)
# 校验返回列表第一条数据的id字段
assert r.json()[0]['id'] == 1
def test_api03():
"""返回非标准JSON,通过文本包含做断言"""
url = "https://jsonplaceholder.typicode.com/"
r = requests.get(url=url)
target_text = "Use your own data"
assert target_text in r.text
接口自动化断言示例里用到是 免费学习API资源:http://jsonplaceholder.typicode.com/
7. 参数化
当同一个测试逻辑,需要使用多组测试数据验证,就需要用到参数化
假设要测试登录功能
测试数据:
| 用户名 | 密码 | 预期结果 |
|---|---|---|
| admin | 123456 | 登录成功 |
| test | 888888 | 登录成功 |
| admin | 123 | 登录失败 |
如果不使用参数化:
def test_login_01():
username = "admin"
password = "123456"
assert login(username, password) == "登录成功"
def test_login_02():
username = "test"
password = "888888"
assert login(username, password) == "登录成功"
def test_login_03():
username = "admin"
password = "123"
assert login(username, password) == "登录失败"
代码重复,不方便维护,数据量大时代码爆炸
使用参数化:
Pytest 提供:@pytest.mark.parametrize()装饰器 实现数据驱动测试
示例:
import pytest
@pytest.mark.parametrize(
"username,password",
[
("admin", "123456"),
("test", "888888"),
("guest", "666666")
]
)
def test_login(username, password):
print(username, password)
单参数传递
对单个参数得参数化,参数为统一的类型
示例:
"data":形参名,测试函数 test01(data) 的入参变量;(1,2,3):参数数据源(元组),一共 3 组数据:1、2、3。
@pytest.mark.parametrize("data",(1, 2, 3))
def test01(data):
print(data)
执行结果:
参数不是统一的类型
示例:
@pytest.mark.parametrize("data",(1, 'hr', True))
def test02(data):
print(data)
执行结果:
多参数传递
对多个参数得参数化
示例:
"test_input,expected":两个入参变量名,和函数形参一一对应;[("3+5",8),("2+4",6),("6*9",54)]:列表嵌套元组,3 组测试用例数据
@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+4",6),("6*9",54)])
def test_eval(test_input, expected):
assert eval(test_input) == expected
执行结果:
对类进行参数化
也可以在类或模块上使⽤ parametrize 标记,这将使⽤参数集调⽤多个函数
示例:
@pytest.mark.parametrize("n,expected",[(1, 2),(2, 3)])
class Test01:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert n + 1 == expected
执行结果:
对模块中的所有测试进行参数化,可以使用 pytestmark 全局变量赋值
pytestmark = pytest.mark.parametrize("n,expected",[(1, 2),(2, 3)])
class Test01:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert n + 1 == expected
class Test02:
def test_simple_case02(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case02(self, n, expected):
assert n + 1 == expected
执行结果:
自定义参数化数据源
示例:
data_provider()是自定义数据函数,返回列表 [“a”,“b”,“c”]parametrize第二个参数直接调用函数,拿到数据源:“a”、“b”、"c"三组数据
def data_provider():
return ["a","b","c"]
@pytest.mark.parametrize("data",data_provider())
def test_data(data):
assert data != None
print(data)
执行结果:

8. Fixture 机制
pytest 中的 fixture是⼀种强⼤的机制,⽤于提供测试函数所需的资源或上下⽂。它可以⽤于设置测试环境、准备数据等。
简单来说有四个方面:
- 测试前置处理
- 测试后置处理
- 数据共享
- 环境初始化
使⽤与不使⽤fixture标记对比
不使用:
未标记 fixture 方法的调用–函数名来调用
def fixrure_01():
print("第一个fixture方法")
def test_01():
fixrure_01()
print("第一个测试用例")
执行结果:
使用:
@pytest.fixture
def fixrure_01():
print("第一个fixture方法")
def test_01(fixrure_01):
print("第一个测试用例")
执行结果:
未标记 fixture方法 的调用与 fixture 标记的方法调用完全不一样,前者需要在方法体中调用,而后者可以将函数名作为参数进行调用
测试脚本中存在的很多重复的代码、公共的数据对象时,使用 fixture 最为合适
示例1:重复的代码
@pytest.fixture
def fixrure_01():
print("第一个fixture方法")
def test_01(fixrure_01):
print("第一个测试用例")
def test_02(fixrure_01):
print("第二个测试用例")
def test_03(fixrure_01):
print("第三个测试用例")
执行结果:
示例2:测试博客
@pytest.fixture
def login():
print("登录")
def test_blogList(login):
print("测试博客列表页")
执行结果:
fixture 可以嵌套使用
示例:
@pytest.fixture
def first():
print("first")
@pytest.fixture
def second(first):
print("second")
def test(second):
print("test")
执行结果:

Yield Fixture
Yield Fixture 是 pytest 测试框架中,用 yield 实现前置准备 + 后置清理一体化的 fixture 写法
示例1:
执行流程:
- pytest 运行 test_05,发现参数 operator,调用对应 fixture
- 执行到 yield 100,暂停,把 100 传给测试函数
- 测试函数执行完毕(无论成功 / 抛异常)
- pytest 回到 fixture,执行 yield 之后的 print
@pytest.fixture
def operator():
print("前置操作:数值初始化")
yield 100
print("后置操作:数据清理")
def test_05(operator):
assert operator == 100
执行结果:
示例2:利用yield 操作文件
txt文件内容:

def file_read():
print("打开文件")
f = open('text.txt', 'r')
yield f
print("关闭文件")
f.close()
def test_file(file_read):
r = file_read
str = r.read(-1)
print(str)
执行结果:
带参数的fixture
带参数的 Fixture = 可以动态产生不同测试环境或资源的 Fixture
语法格式:
pytest.fixture(scope='', params='', autouse='', ids='', name='')
查看 fixture 源码可知,参数覆盖很广
参数详解:
| 参数 | 说明 | 示例 |
|---|---|---|
scope |
控制 Fixture 的作用范围(生命周期) | scope="function" |
autouse |
是否自动执行 Fixture,默认 False |
autouse=True |
params |
Fixture 参数化,每个参数都会执行一次 Fixture | params=["Chrome","Edge"] |
ids |
与 params 配合使用,为参数设置可读名称 |
ids=["谷歌","微软"] |
name |
给 Fixture 指定别名 | name="login_user" |
scope
scope 参数详解:
| 取值 | 作用 |
|---|---|
function(默认) |
每个测试函数执行一次 Fixture |
class |
同一个测试类共享一个 Fixture |
module |
同一个模块(一个 .py 文件)共享一个 Fixture |
session |
整个测试会话(所有被 pytest 运行的用例)共享一个 Fixture |
示例1:scope=“function”
# 1. function
@pytest.fixture(scope="function")
def fixture_01():
print("初始化")
yield
print("清理")
class TestCase01:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
执行结果:
示例2:scope=“class”
# 2. class
@pytest.fixture(scope="class")
def fixture_02():
print("初始化")
yield
print("清理")
class TestCase02:
def test_01(self, fixture_02):
print("第一个测试用例")
def test_02(self, fixture_02):
print("第二个测试用例")
执行结果:
scope 默认为 function,这里的 function 可以省略不写,当 scope="function" 时,每个测试函数都会调用一次fixture。scope="class" 时,在同一个测试类中,fixture 只会在类中的第一个测试函数开始前执行一次,并在类中的最后一个测试函数结束后执行清理。
示例3:scope=“module” 和 scope=“session”
module 和 session ⽤于实现全局的前后置应⽤,这⾥需要多个⽂件的配合,这种结合的方式使得可以在整个测试项目中定义和维护通用的前后置逻辑,使测试代码更加模块化和可维护
规则:
conftest.py是一个单独存放的夹具配置文件,名称是固定的不能修改- 你可以在项目中的不同目录下创建多个
conftest.py文件,每个conftest.py文件都会对其所在目录及其子目录下的测试模块生效 - 在不同模块的测试中需要用到
conftest.py的前后置功能时,不需要做任何的 import 导入操作 - 作用: 可以在不同的 .py 文件中使用同一个 fixture 函数
项⽬结构:
object/
├── conftest.py # 对所有 object/ 下的用例生效
├── cases/
│ └── test_case05.py
│ └── test_case06.py
当scope=“module” 时:
conftest.py:
@pytest.fixture(scope="module")
def fixture_01():
print("初始化")
yield
print("清理")
test_case05.py:
class TestCase01:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
class TestCase02:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
test_case06.py
class TestCase03:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
执行结果:
当scope=“session” 时:
conftest.py:
@pytest.fixture(scope="session")
def fixture_01():
print("初始化")
yield
print("清理")
test_case05.py
class TestCase01:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
class TestCase02:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
test_case06.py
class TestCase03:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
执行结果:
对比:
autouse
autouse 参数默认为 False 。如果设置为 True,则每个测试函数都会⾃动调⽤该 fixture,⽆需显式传⼊
项⽬结构:
object/
├── conftest.py # 对所有 object/ 下的用例生效
├── cases/
│ └── test_case05.py
│ └── test_case06.py
示例1:autouse=Flase
conftest.py:
@pytest.fixture(scope="session",autouse=Flase)
def fixture_01():
print("初始化")
yield
print("清理")
test_case05.py
class TestCase01:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
class TestCase02:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
test_case06.py
class TestCase03:
def test_01(self,fixture_01):
print("第一个测试用例")
def test_02(self,fixture_01):
print("第二个测试用例")
执行结果:
示例2:autouse=True
conftest.py:
@pytest.fixture(scope="session",autouse=True)
def fixture_01():
print("初始化")
yield
print("清理")
test_case05.py
class TestCase01:
def test_01(self):
print("第一个测试用例")
def test_02(self):
print("第二个测试用例")
class TestCase02:
def test_01(self):
print("第一个测试用例")
def test_02(self):
print("第二个测试用例")
test_case06.py
class TestCase03:
def test_01(self):
print("第一个测试用例")
def test_02(self):
print("第二个测试用例")
执行结果:

params
主要是用来给 fixture 做参数化,让同一个 fixture 能生成多份不同的实例,依赖它的所有测试用例,都会按参数列表自动执行多次
示例1:
- pytest 发现 data_provider 这个 fixture,它的 params=[1,2,3] 会生成 3 组参数实例
- 依赖它的测试用例 test_data,会自动执行 3 次:
- 第 1 次:request.param = 1 → data_provider 返回 1 → 用例打印 1
- 第 2 次:request.param = 2 → data_provider 返回 2 → 用例打印 2
- 第 3 次:request.param = 3 → data_provider 返回 3 → 用例打印 3
@pytest.fixture(params=[1, 2, 3])
def data_provider(request):
return request.param
def test_data(data_provider):
print(data_provider)
执行结果:
注意!!:实现参数化,前面学习过的
@pytest.mark.parametrize也可以实现,但通过fixture可以实现参数化,我们怎么选?
- 如果你是单条用例需要多组输入 / 输出(比如测试同一个函数的不同参数),用
@pytest.mark.parametrize更直接- 如果你是多个用例都需要同一套参数(比如都要跑 admin/user/guest 三个角色),用
fixture(params=...)更高效,避免重复写参数列表。- 如果参数需要带前置 / 后置操作(比如每个用户都要登录 / 登出),优先用
fixture(params=...),可以把登录登出逻辑统一写在fixture里。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)