测试全绿以后,交付为什么还可能是断的¶
测试集合连续运行两次都通过。你执行 git add .,准备提交,随后发现准备提交的
差异还包含半写的 Dockerfile;README 的集成测试命令使用了不存在的 unit marker;
一处新依赖也没有进入声明文件。
绿色测试是重要证据,但工程交付还要求首次进入者能复现入口、审阅者能理解变更 意图、文档与当前行为一致。否则“在我机器上通过”仍然没有成为可移交的基线。
材料说明¶
本章使用 Git 当前官方语义、Markdown README 和前五章形成的 pytest 配置。不会 实际修改主项目或强制提交,也不规定分支模型与 commit message 规范。
1. README 应让下一位读者完成任务¶
README 不是愿望清单,也不是把所有配置复制一遍。对于当前阶段,首次进入仓库的 人至少应能找到:
- 项目做什么、当前提供什么;
- Python 与依赖准备入口;
- 服务启动命令;
- 单元、集成和完整测试命令;
- API/OpenAPI 入口;
- 当前限制:没有数据库、认证、真实 provider、Docker 或 CI。
测试段落可以是:
## 验证
以下命令均从仓库根目录运行:
- 单元测试:`python -m pytest tests/unit`
- FastAPI 进程内集成测试:`python -m pytest -m integration`
- 完整集合:`python -m pytest`
pytest 的发现路径与 marker 定义以 `pyproject.toml` 为准。
测试使用可控 adapter,不访问真实外部 API。
这段说明把任务入口交给读者,把 marker 的权威定义留在配置。若 README 复制一份 marker 列表、配置又维护另一份,两者迟早漂移。
最危险的文档错误不是“不够漂亮”,而是描述未实现行为:当前没有 Docker 就不要
写 docker compose up;没有 CI 就不要显示虚构徽章。文档应概括当前事实并明确
限制。
2. 你编辑的、暂存的、将提交的不是同一个集合¶
W01-L01-P05 已经区分了工作区、index 和 commit。这里继续使用同一组三层快照:
git status 区分已暂存、未暂存和未跟踪路径;但只看文件名不够。提交前至少分别
复核:
概念|staged diff index 与 HEAD 之间的差异,也就是当前准备进入下一次 commit 的内容;它不等于 编辑器里全部当前文件,也不包含尚未暂存的修改。
设想 README 中“测试命令修正”已经暂存,随后你又在同一文件写了 Docker 草稿但未
暂存。git diff --cached 只显示前者;git diff 显示后者。commit 记录的是
index 中选定内容,不是编辑器里整个文件的当前样子。
同一个文件完全可能同时有 staged 与 unstaged hunk。选择性暂存的意义就在于构造 语义快照;它不能替代验证,但能避免无关草稿混入交付。
3. 单一意图可以跨越代码、测试、配置和文档¶
概念|语义 commit 边界 围绕一个可独立审阅的工程结果,组织使该结果成立所需的代码、测试、配置和文档; 无关重构或尚不可运行的草稿应分离。
“一个 commit 一个意图”不等于“一种文件一个 commit”。建立测试基线可能需要:
实现修正 让业务错误稳定映射为 409
单元测试 证明 core 冲突规则
集成测试 证明 FastAPI 公开 409
pytest 配置 注册 integration marker
README 暴露三类验证入口
这些改动共同使“建立成功与错误路径测试基线”成立,可以作为一个可独立审阅的 工程意图。反之,一次顺手的无关模块重命名、全仓格式化或 Docker 草稿应分离。
按文件类型机械拆成“先提交代码、再提交测试、最后提交文档”,会产生语义不完整的 中间快照:代码变了却没有验证,测试命令变了 README 仍旧过期。是否同组取决于 意图完整性,而非后缀名。
提交消息应概括结果,例如:
若 diff 看不出动机,可在正文补充为何选择进程内 ASGI 边界或为何暂不引入数据库。 “update tests”只描述动作,没有帮助审阅者理解结果。
4. 用一条链审查整套交付¶
概念|可复核交付基线 契约、测试、配置、README 与 Git 快照互相一致,并能由下一位读者从仓库入口复现。 它证明交付可检查,不证明软件没有任何 bug,也不代表课程已经学习完成。
交付前分两段按因果链复核。
从契约走到可重复测试¶
先检查:
- 验证清单中的每项核心目标是否有合适层级?
- core 单元是否证明规则,HTTP 集成是否经过真实 FastAPI 应用?
- 201、422、409 是否有具体公开断言,而不是任意成功/错误?
- 测试是否不访问真实外部服务,fixture 是否恢复状态?
从测试入口走到候选提交¶
再检查:
- 单元、集成、完整集合是否可发现、可选择并连续运行一致?
- README 命令是否从仓库入口可执行,与
pyproject.toml一致? git diff --cached是否只包含这一意图所需的实现、测试、配置与说明?
这个审查只证明交付内容形成了可复核基线,不能证明软件没有任何 bug,也不能证明 学习者已经掌握相关能力。测试和文档都是证据,不是全知证明。
常见误区¶
git status干净就说明提交正确。 它不替你审查每个 staged hunk 的语义。- 代码、测试、文档必须分 commit。 同一意图的跨文件改动可以且常常应该共同出现。
- README 越长越完整。 入口可定位、事实当前且权威来源明确,比复制所有细节重要。
- 测试全绿即可交付。 漏收集、过期命令、缺依赖声明和混合 diff 都可能让交付断链。
本章小结¶
pytest 基线要成为工程交付,必须同时具备可复现入口和可审阅快照。README 从实际 配置提炼任务导航;Git index 精确决定下一 commit;commit 围绕一个工程意图组织 必要代码、测试、配置与文档。最终审查把契约、测试、隔离、运行、说明和 diff 连成一条可追溯链。
练习¶
一个候选 staged diff 包含:
- 修正
PlanConflict→ 409; - 新增 core 冲突单元测试;
- 新增 HTTP 409 集成测试;
- 注册
integrationmarker; - README 新增完整测试命令;
- 重命名三个与测试无关的 domain 模块;
- 增加尚不可运行的 Dockerfile 草稿。
请给出 commit 分组,并说明提交前还要复核哪些证据。
练习解析¶
前五项共同构成“建立业务冲突测试基线”:实现让契约成立,单元/集成分别证明规则 与公开映射,配置提供集合入口,README 让入口可发现。它们可以进入同一 commit。
无关 domain 重命名属于另一个重构意图,应分离;Dockerfile 属于 W01-L05 Target, 当前尚不可运行且越出本课,应从本次 staged diff 排除。
提交前还应:运行 collect 检查;分别运行单元、集成和完整集合;连续运行完整集合;
核对测试不访问外部服务;从 README 复制命令实际执行;检查 git diff 与
git diff --cached;确认依赖声明、配置和说明都在 staged 快照中,且未包含本地
生成物或 secret。