用途
该技能用于在编写、审查、调试 Python 测试或提升测试覆盖率时,指导使用 pytest 写出有效、可维护的测试。
主要能力与规范
测试结构
- 每个测试应原子、自包含,只验证单一行为;测试名应能说明失败时哪里出了问题。多个断言可以接受,但须验证同一行为。
- 同一概念的多种变体使用参数化,例如通过
@pytest.mark.parametrize("input,expected", [...])验证大写转换;不同功能应写成独立测试,不做无关行为的参数化。
项目特定规则
- 项目全局配置
asyncio_mode = "auto",异步测试无需@pytest.mark.asyncio装饰器。 - 所有导入放在文件顶部,不在函数内做局部导入。
- 测试 FastMCP 时优先把服务器直接传给
Client使用内存传输:
from fastmcp import FastMCP
from fastmcp.client import Client
mcp = FastMCP("TestServer")
@mcp.tool
def greet(name: str) -> str:
return f"Hello, {name}!"
async def test_greet_tool():
async with Client(mcp) as client:
result = await client.call_tool("greet", {"name": "World"})
assert result[0].text == "Hello, World!"
仅在明确测试网络功能时才使用 HTTP 传输。
- 复杂结构(如 JSON schema)使用
inline_snapshot.snapshot做内联快照断言,首次运行自动填充;可用命令pytest --inline-snapshot=create填充空快照,pytest --inline-snapshot=fix在有意变更后更新。
Fixture 与 Mock
- 优先使用函数作用域 fixture;文件操作使用内置
tmp_path。 - 在边界处 mock 外部服务(如
unittest.mock.patch配合AsyncMock),不使用 mock 替代自有内部实现。
命名与错误测试
- 使用描述场景的名称,如
test_login_fails_with_invalid_password、test_admin_can_delete_any_user,避免test_login这类笼统命名。 - 用
pytest.raises并配合match验证异常信息,同步与异步场景分别覆盖。
运行命令
uv run pytest -n auto # 并行运行全部测试
uv run pytest -n auto -x # 首次失败即停止
uv run pytest path/to/test.py # 运行指定文件
uv run pytest -k "test_name" # 按名称模式筛选
uv run pytest -m "not integration" # 排除集成测试
适用场景
编写新测试、审查现有测试代码、定位测试失败原因、提升测试覆盖率,以及需要统一 pytest 编写风格的 Python 项目。
限制
该技能只给出测试编写与运行规范,具体项目结构、依赖安装与 CI 配置暂未提供;文中命令假设使用 uv 作为运行器,其他环境下的等价命令暂未提供。