0 序
1 概述
产品介绍
-
定位 :pytest 是一个面向 Python 的开源测试框架,主打"用最小代价写出可读性高的测试 ",同时可扩展到复杂的功能测试 、集成测试 和端到端测试。
-
核心理念:
- 用普通
assert表达断言 ,由pytest提供失败时的详细信息。 - 用
fixture(固定支具/固定夹具) 管理测试前置条件和清理逻辑。 - 用 markers、parametrize、plugins 组织和扩展测试。
- 保持与
unittest生态的兼容,允许渐进式迁移。
- 用普通
-
解决的核心问题:
- 降低测试代码编写成本。
- 减少传统
unittest中大量的样板代码。 - 统一测试发现、参数化、跳过、失败报告和插件扩展机制。
-
URLs:
当前项目状态
| 指标 | 数据 |
|---|---|
| 最新版本 | 9.1.1 |
| 最新版本发布时间 | 2026-06-19 |
| 支持的 Python 版本 | Python 3.10+ |
| License | MIT |
| GitHub Stars | 14,493 |
| GitHub Forks | 3,354 |
| Open Issues/PRs | 815 |
| 最近一次推送 | 2026-09-08 |
数据来源:GitHub API、PyPI API,查询时间为 2026-09-10。
发展历程
pytest的历史较长,官方 README 中标注的项目版权起点为 2004 年 ,现代版本的公开发布记录可以从 1.0 之后清晰追溯。
| 时间 | 事件 |
|---|---|
| 2004 | 项目版权起点,早期与 py / py.test 生态相关。 |
| 2009-08-04 | 发布 1.0.0,现代 pytest 版本线开始清晰化。 |
| 2010-11-25 | 发布 2.0.0。 |
| 2016-08-19 | 发布 3.0.0;官方文档提到该阶段引入了更清晰的弃用与兼容策略。 |
| 2018-11-14 | 发布 4.0.0。 |
| 2019-06-29 | 发布 5.0.0。 |
| 2020-07-28 | 发布 6.0.0。 |
| 2022-02-04 | 发布 7.0.0。 |
| 2024-01-27 | 发布 8.0.0,最低支持 Python 3.8。 |
| 2025-11-05 | 发布 9.0.0,最低支持提升到 Python 3.10。 |
| 2026-06-19 | 发布当前最新版本 9.1.1。 |
从长期演进看,pytest 的主线是:
- 保持测试写法简单。
- 强化 fixture 和插件体系。
- 逐步收紧兼容边界。
- 跟随 Python 版本演进。
- 维持庞大的第三方插件生态。
主要功能
-
自动测试发现
- 默认收集
test_*.py、*_test.py文件。 - 默认收集
test_*函数和Test*类。
- 默认收集
-
增强断言
- 使用普通
assert。 - 失败时自动输出上下文。
- 支持
pytest.approx做近似比较。
- 使用普通
-
Fixture 依赖注入
- 测试通过函数参数声明依赖。
- 支持分层、复用、缓存和 teardown。
-
参数化测试
@pytest.mark.parametrize可将一组输入展开成多个测试用例。- 支持组合参数、pytest.param、id、marks。
-
Markers
- 支持内置 marker 和自定义 marker。
- 可用
-m进行测试选择。
-
插件体系
- 内置插件。
conftest.py本地插件。- 第三方插件生态。
-
测试输出控制
-v、-q、-s、--tb=short等。- 支持
capsys、caplog、tmp_path等内置 fixture。
-
跳过与预期失败
skip、skipif、xfail。
-
兼容
unittest- 可以直接运行大量已有
unittest.TestCase测试。
- 可以直接运行大量已有
-
报告与调试
--durations输出耗时。--pdb在失败处进入调试器。
核心优势
- 上手成本低
- 一个普通 Python 函数加一个
assert就是一个测试。
- 一个普通 Python 函数加一个
- 断言体验好
- 不需要记忆大量
self.assertEqual之类的 API。
- 不需要记忆大量
- fixture 系统强
- 相比传统 setup/teardown,fixture 更适合组合、复用和分层。
- 参数化能力强
- 一段测试逻辑可以自动展开成多组用例。
- 生态极大
- 官方 README 提到外部插件超过 1300 个。
- 常见方向包括覆盖率、并行执行、Django、asyncio、mock、数据库等。
- 与
unittest兼容- 老 项目可以渐进迁移,不必一次性重写。
- 社区成熟
- 长期维护、版本发布稳定、贡献者众多。
- 适合 CI/CD
- 命令行接口稳定,易于接入 GitHub Actions、GitLab CI、Jenkins 等系统。
主要短板
- 【插件组合】可能带来维护成本
- 多个第三方插件同时修改收集、报告、fixture 行为时,可能产生兼容性问题。
- 【隐式行为】较多
- fixture、autouse、conftest、marker 组合可能降低代码可读性。
- 复杂测试的【可读性】依赖团队约定
- 如果滥用高作用域 fixture,测试之间可能出现隐性共享状态。
- 【并行执行】并非完全内置
- 官方核心不内置完整并行调度,通常需要
pytest-xdist。
- 官方核心不内置完整并行调度,通常需要
- 对【非常规测试场景】需要插件
- 例如 Web UI 测试、数据库快照、分布式环境等,通常要结合其他工具或插件。
- 大型测试套件收集【成本】可能上升
- 项目很大时,应控制
testpaths、导入路径和插件加载范围。
- 项目很大时,应控制
局限性
- 仅是【测试框架】,不是【完整的测试管理平台】
- 不内置测试计划、需求映射、用例评审等产品级功能。
- 不能解决所有【测试设计】问题
- fixture 再强,也不能替代良好的测试分层和领域建模。
- 对 Python 版本有要求
- 当前
9.x只支持Python 3.10+。
- 当前
- 非 Python 生态支持有限
- 虽然可以通过插件扩展,但核心优势仍在 Python 项目中。
- 内部 API 不适合【直接依赖】
- 第三方插件应尽量使用公开 API 和 hook,避免绑定内部实现细节。
适用场景
- Python 库或应用的单元测试。
- 服务端 API 集成测试。
- 数据库访问层测试。
- CLI 工具测试。
- 数据处理管道测试。
- 需要大量参数化场景的算法测试。
- 需要渐进迁移的
unittest项目。 - CI/CD 中的自动化回归测试。
- 需要利用插件生态扩展覆盖率、并行、mock、日志等能力的项目。
不适合或需要谨慎使用的场景:
- 测试之间强依赖、共享大量全局状态。
- 希望只靠框架解决测试质量和测试分层问题。
- 期望一个工具同时承担测试管理、用例设计和缺陷跟踪。
同类竞品
| 竞品 | 定位 | 与 pytest 的关系 |
|---|---|---|
unittest |
Python 标准库测试框架 | 更稳定、零依赖,但样板代码更多;pytest 可运行大部分 unittest 测试。 |
nose2 |
unittest 扩展 | 曾经流行,但生态活跃度和插件生态弱于 pytest。 |
doctest |
文档示例测试 | 适合校验文档示例,不适合作为完整测试框架。 |
Robot Framework |
关键字驱动验收测试 | 更偏业务流程和 E2E,Python 编程能力不如 pytest 灵活。 |
Hypothesis |
属性测试 | 可与 pytest 结合,属于互补关系。 |
tox / nox |
多环境管理 | 不是测试 runner 本身,常与 pytest 搭配使用。 |
| 自研测试框架 | 企业内部定制 | 官方生态通常更成熟,自研成本高。 |
发展趋势
-
社区活跃度高
- 截至 2026-09-10,最近一次推送为 2026-09-08。
- 2026 年内已发布多个版本,最新为
9.1.1。
-
Star / Fork 规模大
- GitHub Stars 当前为 14,493,Forks 为 3,354。
- Star 趋势图:pytest Star History
-
生态继续向工程化扩展
- 覆盖率、并行、异步、数据库、Web、云环境等方向依赖插件生态快速发展。
-
兼容策略更清晰
- 官方维护了较明确的弃用、迁移和兼容政策。
-
总结
- pytest 已经从"更好用的 unittest 替代品"发展成 Python 测试生态的事实标准,未来重点会继续放在兼容性、插件生态和大规模工程化上。
2 工作原理与架构
概念术语
| 术语 | 含义 |
|---|---|
test item |
一条可执行的测试用例。 |
collector |
负责发现和生成测试项的对象。 |
fixture |
为测试提供前置状态、资源或环境的机制。 |
scope |
fixture 的生命周期范围。 |
marker |
附加在测试上的元数据。 |
parametrize |
把一组参数展开为多个测试用例。 |
conftest.py |
目录级配置和本地插件文件。 |
plugin |
扩展 pytest 行为的模块或包。 |
hook |
插件介入 pytest 生命周期的切入点。 |
assertion rewriting |
pytest 通过 AST 重写增强普通 assert 的失败信息。 |
架构与运行原理
pytest 的核心流程可以概括为:
- 解析命令行参数和配置文件。
- 加载 内置插件、第三方插件和
conftest.py。 - 构建【测试收集树】。
- 解析【测试依赖】,包括 fixture、marker、parametrize。
- 执行【测试用例】。
- 收集断言结果和输出。
- 执行 teardown。
- 生成报告、缓存和退出码。
结构示意:
flowchart LR ACLI / config --> BPlugin manager B --> CHooks C --> DTest collection tree D --> EFixture resolution E --> FRun test item F --> GAssert / report F --> HTeardown G --> ICache / exit code
运行阶段
| 阶段 | 主要动作 |
|---|---|
| 启动 | 解析 pytest.ini、pyproject.toml、命令行参数。 |
| 插件加载 | 注册内置插件、外部插件和 conftest.py。 |
| 收集 | 根据命名规则和配置收集测试。 |
| 解析 | 分析 fixture、marker、parametrize。 |
| 执行 | 调用测试函数或测试类方法。 |
| 报告 | 汇总 pass、fail、skip、xfail、warning。 |
| 清理 | 逆序执行 fixture teardown。 |
| 退出 | 返回 0 到 6 的退出码。 |
fixture 生命周期
pytest 默认 fixture 作用域是 function。常见作用域包括:
function:每个测试函数独立创建和销毁。class:同一个测试类内共享。module:同一个测试模块内共享。package:同一个包内共享。session:整个测试会话内共享。
3 使用指南
安装部署
Linux
bash
python3 -m pip install -U pytest
python3 -m pytest --version
Windows
powershell
py -m pip install -U pytest
py -m pytest --version
例如:
shell
(base) PS F:\Codes-Minor\Github\ai-chatbot> .\.venv\Scripts\python -m pytest --version
pytest 8.4.2
如果不使用 py 启动器,也可以使用:
powershell
python -m pip install -U pytest
python -m pytest --version
推荐项目结构 (必读)
text
project/
├── src/
│ └── your_package/
├── tests/
│ ├── conftest.py
│ ├── test_unit.py
│ └── test_integration.py
├── pyproject.toml
└── README.md

常见配置
requirements-dev.txt 示例
txt
-r requirements.txt
...
pytest>=8.3.0,<9

pyproject.toml 示例
toml
[tool.pytest.ini_options]
minversion = "8.0"
addopts = "-ra --strict-markers"
testpaths = ["tests"]
markers = [
"slow: marks tests as slow",
"integration: requires external services",
]
常用配置含义:
testpaths:限制默认收集范围,提升速度。addopts:为每次运行追加默认参数。--strict-markers:未注册 marker 直接报错。markers:显式注册自定义 marker,减少拼写错误。
常见用法
基本测试 (必读)
python
# tests/test_basic.py
def inc(x):
return x + 1
def test_answer():
assert inc(3) == 4
- 运行:
bash
pytest tests/test_basic.py
或:
bash
python -m pytest tests/test_basic.py
或 .\.venv\Scripts\python -m pytest tests/test_basic.py -v
-v参数 :--verbose参数的缩写,表示 让 pytest 以更详细的方式输出测试结果。
- 不加
-v时,输出通常比较简洁:
txt
tests/test_basic.py . [100%]
- 加
-v后,会显示完整的测试路径和测试名:
txt
tests/test_basic.py::test_answer PASSED [100%]
tests/test_basic.py::test_eval PASSED [100%]
tests/test_basic.py::test_login FAILED [100%]
相关参数: -q/-v/-vv/-s (必读)
| 参数 | 含义 |
|---|---|
-q |
quiet,简化输出;只看整体结果时用。 |
-v |
verbose,显示每个测试的完整 ID 和状态。 |
-vv |
更详细;例如显示更完整的断言差异。 |
-s |
显示测试里的 print() 输出。 |
-s参数的示例

运行指定测试:文件/函数/类/类方法 (必读)
bash
# 按文件/File
pytest tests/test_api.py
# 按函数/Function
pytest tests/test_api.py::test_create_user
# 按类/Class
pytest tests/test_api.py::TestUsers
# 按类方法/Class::Method
pytest tests/test_api.py::TestUsers::test_create_user
按表达式筛选(-k)

bash
pytest -k "login and not slow"
# 注: 运行测试 ID 中包含 login 的测试,但排除名称中包含 slow 的测试。这里的"【名称】"包括:文件名、类名、函数名。
pytest -k "TestUsers or test_create"
pytest -k "not integration"
注意:
-k参数匹配的是"测试名称 "里的关键词,不是marker。
-kvs-m(marker)
| 参数 | 匹配对象 |
|---|---|
-k |
文件名、类名、函数名中的关键词 |
-m |
@pytest.mark.xxx 定义的 marker |
按 marker 筛选
定义、使用
Marker是 pytest 里的**"测试标签/元数据"机制**。
- 核心用途:给测试打标记,然后可以按标记筛选、跳过、归类,或让插件识别这些标签并做出特殊处理。
- 例如:
python
import pytest
@pytest.mark.slow
def test_login():
...
这句话的意思不是"这个测试会自动变慢",而是:给
test_login这个测试用例打上一个名为slow的标签。
- 之后可以在命令行按 marker 筛选:
shell
pytest -m slow # 只运行带 slow 标记的测试
pytest -m "not slow" # 运行所有不带 slow 标记的测试
pytest -m "live and not slow"
2种写法
- 写法1:
pytest.mark.slow:标记单个测试
python
import pytest
@pytest.mark.slow
def test_login():
...
含义:
test_login这个测试被标记为slow。运行:
shell
pytest -m slow
就会选中它。
- 写法2:
pytestmark = pytest.mark.live:标记整个模块
python
import pytest
pytestmark = pytest.mark.live
def test_login():
...
def test_logout():
...
- 含义:当前这个测试模块里的所有测试,都会被标记为
live。等价于给模块里的每个测试都打上 live 标签:
python
@pytest.mark.live
def test_login():
...
@pytest.mark.live
def test_logout():
...
live marker = 通常是团队自定义的 marker

- 通常
live是团队自定义的 marker,常见含义是:
- 需要真实外部环境;
- 会访问真实网络 或真实数据库;
- 运行成本 高、可能有副作用;
- 【不适合】默认在单元测试 中跑。
例如:
shell
# 默认不跑需要真实环境的测试。
pytest -m "not live"
内置 marker vs 自定义 marker
pytest 自带一些有特殊行为的 marker,例如:
| Marker | 含义 |
|---|---|
pytest.mark.skip |
无条件跳过 |
pytest.mark.skipif |
条件跳过 |
pytest.mark.xfail |
预期失败 |
pytest.mark.parametrize |
参数化测试 |
pytest.mark.usefixtures |
显式使用 fixture |
pytest.mark.filterwarnings |
过滤警告 |
- 而
live、slow、serial通常是项目自定义标签 。它们默认只是元数据,不会自动改变测试行为;需要配合-m、插件或 hook 使用。
建议在配置里注册,例如:
toml
[tool.pytest.ini_options]
markers = [
"live: tests that require a live external environment",
"slow: tests that are slow to run",
]
注册后,pytest 能识别这些 marker,避免"未知 marker"警告。
常用运行参数 (必读)
| 命令 | 作用 |
|---|---|
pytest -v |
显示更详细的测试名。 |
pytest -q |
安静模式。 |
pytest -s |
禁用输出捕获,直接显示 print。 |
pytest -x |
首个失败后停止。 |
pytest --maxfail=3 |
失败 3 次后停止。 |
pytest --tb=short |
简短 traceback。 |
pytest --tb=long |
详细 traceback。 |
pytest --durations=10 |
显示最慢的 10 个测试。 |
pytest --pdb |
失败后进入调试器。 |
pytest --collect-only -q |
只收集不执行。 |
pytest --fixtures |
查看可用 fixture。 |
pytest --markers |
查看可用 marker。 |
基础 fixture (依赖注入机制) ------ 提前准备数据与资源
@pytest.fixture是pytest的 依赖注入机制 ,用来为测试准备它们需要的资源或状态。
- 通俗理解:
@pytest.fixture就是把"测试的前置准备 "变成可复用的依赖 ;测试只要写参数名,pytest负责准备和注入。- 核心规则: 测试函数声明什么参数名,pytest 就自动找同名 fixture,执行它并把返回值注入进来。例如:
python
import pytest
@pytest.fixture
def user():
return {"id": 1, "name": "Alice"}
def test_user_name(user):
assert user["name"] == "Alice"
这里的
user不是普通参数 ,而是由fixture机制提供的测试数据。
- 常见用途:
- 构造测试对象
- 创建数据库/HTTP 客户端
- 准备临时目录
- 初始化日志、配置
- 在测试后清理资源
例如:
python
@pytest.fixture
def client():
app = create_app()
with app.test_client() as c:
yield c
fixture teardown(测试后清理机制)
fixture teardown是 pytest 的 测试后清理机制 ,用于在测试完成后释放资源、恢复状态。
tear down: 英译: 拆卸、销毁
- 核心写法:
python
import pytest
@pytest.fixture
def db():
conn = connect_db()
yield conn # 交给测试使用
conn.close() # teardown 机制:测试结束后执行
- 执行顺序:
- 执行 fixture 前半段,创建资源。
yield conn把资源注入测试。- 测试运行。
- 执行
yield后面的清理代码。
- 常见清理内容:
- 关闭数据库连接、文件句柄、HTTP session
- 删除临时数据
- 恢复环境变量
- 停止容器或服务
- 回滚事务
- 小结:
@pytest.fixture负责准备资源 ;yield之后的代码负责收尾。
- 示例:
python
import pytest
@pytest.fixture
def service():
svc = start_service()
yield svc
svc.stop() # teardown 机制: `yield` 之后的代码负责【收尾】
def test_health(service):
assert service.healthcheck() is True
执行顺序:
start_service()yield svc- 测试执行
svc.stop()------ 测试后的后置动作 (teardown 特性)
fixture 作用域(scope)
python
import pytest
@pytest.fixture(scope="module")
def client():
return create_client()
def test_a(client):
...
def test_b(client):
...
- 同一个测试模块内,
client只会创建一次。
参数化测试
python
import pytest
@pytest.mark.parametrize(
("value", "expected"),
[
(1, 1),
(-2, 2),
(0, 0),
],
)
def test_abs(value, expected):
assert abs(value) == expected
带 ID:
python
@pytest.mark.parametrize(
("value", "expected"),
[
pytest.param(1, 1, id="positive"),
pytest.param(-2, 2, id="negative"),
],
)
def test_abs(value, expected):
assert abs(value) == expected
临时目录
python
def test_write_config(tmp_path):
path = tmp_path / "config.yaml"
path.write_text("debug: true", encoding="utf-8")
assert path.read_text(encoding="utf-8") == "debug: true"
会话级临时目录:
python
import pytest
@pytest.fixture(scope="session")
def data_dir(tmp_path_factory):
return tmp_path_factory.mktemp("data")
Monkeypatch 环境变量
python
import os
def test_app_mode(monkeypatch):
monkeypatch.setenv("APP_MODE", "test")
assert os.environ["APP_MODE"] == "test"
Mock 属性或函数
python
from pathlib import Path
def get_ssh_path():
return Path.home() / ".ssh"
def test_get_ssh_path(monkeypatch):
monkeypatch.setattr(Path, "home", lambda: Path("/abc"))
assert get_ssh_path() == Path("/abc/.ssh")
捕获 stdout
python
def test_stdout(capsys):
print("hello")
captured = capsys.readouterr()
assert captured.out == "hello\n"
近似比较
python
import pytest
def test_float():
assert 0.1 + 0.2 == pytest.approx(0.3)
conftest.py 共享 fixture
python
# tests/conftest.py
import pytest
@pytest.fixture
def api_client():
client = create_test_client()
yield client
client.close()
在任意子目录测试中直接使用:
python
# tests/api/test_users.py
def test_create_user(api_client):
response = api_client.post("/users", json={"name": "Alice"})
assert response.status_code == 201
覆盖率测试
通常配合 pytest-cov:
bash
python -m pip install pytest-cov
pytest --cov=your_package --cov-report=term-missing
并行执行
通常配合 pytest-xdist:
bash
python -m pip install pytest-xdist
pytest -n auto
失败快速停止
bash
pytest -x
失败一批后停止:
bash
pytest --maxfail=5
只查看会执行哪些测试
bash
pytest --collect-only -q

推荐日常工作流 (必读)
- 先运行最窄范围:
bash
pytest tests/test_that_file.py::test_target_case
- 再运行相关模块:
bash
pytest tests/test_that_file.py
- 再运行整个相关包:
bash
pytest tests/api
- 最后运行全量测试:
bash
pytest
- 需要优化速度时,查看耗时:
bash
pytest --durations=10 --durations-min=0.1
Z FAQ for pytest 框架
Q: pytest 能否替代 unittest?
可以替代,但不一定要立刻替换。pytest 可以运行大量已有 unittest.TestCase 测试,因此推荐渐进迁移:
- 新测试直接用 pytest 写。
- 老测试先继续运行。
- 需要重构时再逐步改成 fixture 风格。
Q: pytest 和 unittest 应该选哪个?推荐 pytest
多数 Python 项目更适合选 pytest:
- 断言更简洁。
- fixture 更容易组合。
- 参数化更强。
- 插件生态更丰富。
unittest 更适合:
- 希望零第三方依赖。
- 团队强依赖标准库。
- 与某些旧工具链绑定较深。
Q: 为什么我的测试没有被收集?*(必读)
常见原因:
- 文件名称 不是
test_*.py或*_test.py。 - 函数名不是
test_*。 - 类名不是
Test*,或类主动声明了__init__。 - 测试文件没有被导入,存在 import error。
testpaths配置没有覆盖目标目录。
排查命令:
bash
pytest --collect-only -q
Q: fixture 和 setup/teardown 的区别是什么?
setup/teardown 是过程式的生命周期钩子 ;fixture 是依赖注入式的资源管理机制。
fixture 的优势:
- 可以被多个测试复用。
- 可以依赖其他 fixture。
- 可以设置 scope。
- 可以通过
yield自动清理。 - 可以参数化。
- 可以在
conftest.py中跨目录共享。
Q: 如何让测试之间互相独立?
建议:
- 默认使用
function级 fixture。 - 避免共享可变对象。
- 使用
tmp_path管理临时文件。 - 使用
monkeypatch修改属性和环境变量。 - 数据库测试使用事务回滚或独立数据快照。
- 避免依赖测试执行顺序。
Q: 如何跳过测试?(必读)
- 注解方式1
python
import sys
import pytest
@pytest.mark.skipif(sys.platform == "win32", reason="POSIX only")
def test_posix_feature():
...
- 注解方式2: 无条件跳过:
python
@pytest.mark.skip(reason="temporary disabled")
def test_not_ready():
...
- 方式3: 运行时条件跳过:
python
import pytest;
def test_feature():
if not feature_enabled():
pytest.skip("feature not enabled")
Q: 如何标记预期失败?(必读)
python
@pytest.mark.xfail(reason="known bug #123", strict=True)
def test_known_bug():
...
- 参数化中的预期失败:
python
import pytest
@pytest.mark.parametrize(
("value", "expected"),
[
(1, 1),
pytest.param(-1, -1, id="known-bug", marks=pytest.mark.xfail),
],
)
def test_normalize(value, expected):
assert abs(value) == expected
Q: 如何测试异常和警告?
异常
python
import pytest
def parse_value(value):
if value is None:
raise ValueError("bad input")
return int(value)
def test_bad_input():
with pytest.raises(ValueError, match="bad input"):
parse_value(None)
警告
python
import warnings
import pytest
def test_warning():
with pytest.warns(UserWarning, match="deprecated"):
warnings.warn("deprecated API", UserWarning)
Q: 如何并行运行?
核心包不内置完整并行能力,通常使用 pytest-xdist:
bash
python -m pip install pytest-xdist
pytest -n auto
前提是测试必须相互独立。对数据库、临时目录、端口等资源要做好隔离。
Q: pytest 的退出码代表什么?(必读)
| 退出码 | 含义 |
|---|---|
| 0 | 全部通过 |
| 1 | 有测试失败 |
| 2 | 用户中断 |
| 3 | pytest 内部错误 |
| 4 | 命令行或配置错误 |
| 5 | 没有收集到测试 |
| 6 | 超过最大警告数 |
Y 推荐文献
- Pytest
- Github: https://github.com/pytest-dev/pytest/
- 官方文档: https://docs.pytest.org/en/stable/
- Getting started: https://docs.pytest.org/en/stable/getting-started.html
- How to invoke pytest - pytest
- How to use fixtures - pytest
- Parametrize tests - pytest
- Monkeypatch and environment - pytest
- Writing plugins - pytest