# pytest 快速上手示例
一个最小化的 pytest 演示项目,包含一个简单的计算器模块和对应的测试用例。
## 目录结构
```
pytest_doc/
├── src/
│ └── calculator.py # 被测代码:加减乘除 + 判断偶数
├── tests/
│ └── test_calculator.py # 测试用例:断言 / 异常 / 参数化 / fixture
├── pytest.ini # pytest 配置
├── pyproject.toml # ruff(lint + format)配置
├── requirements.txt # 依赖
└── README.md
```
## 环境准备
```bash
# 1. (可选)创建并激活虚拟环境
python -m venv venv
# Windows PowerShell:
venv\Scripts\Activate.ps1
# Linux / macOS:
source venv/bin/activate
# 2. 安装依赖
pip install -r requirements.txt
```
## 开发人员如何运行 pytest
在项目根目录 `pytest_doc/` 下执行:
| 目的 | 命令 |
| --- | --- |
| 运行全部测试 | `pytest` 或 `python -m pytest` |
| 详细输出(显示每个用例) | `pytest -v` |
| 只运行某个文件 | `pytest tests/test_calculator.py` |
| 只运行某个用例 | `pytest tests/test_calculator.py::test_add` |
| 按名称关键字筛选 | `pytest -k "divide"` |
| 遇到第一个失败就停止 | `pytest -x` |
| 显示 print 输出 | `pytest -s` |
| 查看测试结果摘要 | `pytest -ra` |
| 生成覆盖率报告(需 pytest-cov) | `pytest --cov=src` |
> 推荐使用 `python -m pytest`,它会把当前目录加入 `sys.path`,避免导入路径问题。
## 预期结果
```
============================= test session starts =============================
collected 11 items
tests/test_calculator.py::test_add PASSED [ 9%]
...
============================= 11 passed in 0.08s ==============================
```
## 代码检查(ruff:lint + 格式化)
[ruff](https://docs.astral.sh/ruff/) 是一个用 Rust 写的高性能工具,**一个工具同时替代 flake8(lint)+ isort(导入排序)+ black(格式化)**。配置写在 `pyproject.toml` 里。
在项目根目录 `pytest_doc/` 下执行:
| 目的 | 命令 |
| --- | --- |
| 检查代码问题(lint) | `ruff check .` |
| 自动修复可修复的问题 | `ruff check --fix .` |
| 检查格式(不修改文件) | `ruff format --check .` |
| 自动格式化代码 | `ruff format .` |
> 推荐流程:先 `ruff check --fix .` 修 lint,再 `ruff format .` 统一格式,最后 `pytest` 跑测试。
> 启用的规则集:`E/W`(PEP8) `F`(pyflakes) `I`(isort) `B`(bugbear) `UP`(pyupgrade)。
### 一键质量检查
```bash
ruff check . && ruff format --check . && pytest
```
CI 流水线里通常就是这一行:任意一步失败则整体失败。
## 示例中演示的 pytest 核心知识点
1. **基本断言**:直接用 Python 的 `assert`,pytest 会自动给出详细的失败信息。
2. **异常断言**:`with pytest.raises(ValueError, match="..."):` 校验函数是否按预期抛异常。
3. **参数化** `@pytest.mark.parametrize`:一份测试逻辑跑多组输入/输出数据。
4. **fixture** `@pytest.fixture`:为测试提供可复用的前置数据或资源。