用途:面向个人、由智能体维护的 Python 项目,专门约束测试套件的写法(从 python-conventions-taudelta 拆分,后者保留设计与风格默认)。不包含工具配置,pytest 自身配置属于仓库质量工具。
主要能力与约定:
- fixture 优先。测试所需任何准备(tmp 目录树、假 HOME、打桩的 c.run、构造对象、monkeypatch 环境)都写成 pytest fixture,两个文件以上需要时放进 conftest.py,而非在每个测试体内手写。优先用内置 tmp_path、monkeypatch、capsys、caplog;仅当需要每次调用传参时用辅助函数,通常可改为返回工厂的 fixture(如 make_repo(name))。
- 跨平台陷阱:expanduser 在 POSIX 读 HOME、Windows 读 USERPROFILE,只设其一会在每次测试写入真实用户目录;写入 TOML/JSON 的路径用 path.as_posix()(TOML 基本字符串中反斜杠是转义,C:\Users 为非法 \U);所有 read_text/write_text 传 encoding="utf-8",否则平台默认代码页会乱码或解码失败;比较路径列表也经 as_posix()(Path("/repo") 渲染为 \repo);把平台接缝(如被测模块中 WINDOWS = os.name == "nt")固定到 fixture 所写的分支。
- fixture 作用域取保持正确的最窄范围。模块单例在模块/会话级构造,用函数级 fixture 重置其可变状态;宽作用域 fixture 中的 monkeypatch 会在整个作用域存活,可能造成静默的跨测试泄漏。
- DAMP 与 DRY:准备机制(fixture/辅助、how)保持 DRY;测试所验证的场景(what)保持显式、可从上到下读懂。真正的输入→期望矩阵用 parametrize,值不再自明时加 ids。判断线:新增用例只是加值就用 parametrize;改变测试逻辑(分支、不同准备、不同断言)就写新测试。避免把不同场景折进一个带分支的巨型测试,或藏进名称不说明断言内容的辅助。
- 不要在测试的被测行为中运行会改代码的命令,除非变异本身是测试对象。检查前先跑修复/格式化会掩盖只读检查本可发现的缺陷;测试中优先用 check-only/干跑形式。
- 不重复真实可运行的东西:套件能完整拥有生命周期的依赖(进程内或自行启停的子进程)不用 mock/fake/stub,如 SQLite 文件、临时目录、本地队列、自己子进程中的入口点都跑真实的;第三方 HTTP API 是界线另一侧,手写替身是正确的。判断标准是生命周期,而非技术清单。真实不等于沙箱:被测真实服务同样需要自己的临时状态。框架单例使进程内安排不诚实时,用子进程 fixture,配以有界就绪等待并在失败时输出子进程内容,避免无限挂起。
用法:该文件安装时被复制到 ~/.agents/skills/python-testing-conventions-taudelta,绝不符号链接,故编辑部署副本只是本机漂移,不会到达其他机器。应在安装来源仓库中改源、推送,再运行 skills add <that source> --global --skill python-testing-conventions-taudelta 刷新各项目副本。若从他人仓库安装,来源归其所有,应在其处提 issue 或 pull request。
限制:资料未提供具体返回码、输出格式、超时默认值、支持平台清单等细节。完整理由见 references/rationale.md,可运行示例见 references/snippets/testing.py。