本系列:00 导读 · 01 心智模型 · 02 路由与数据模型 · 03 依赖注入与分层 · 04 中间件异常日志 · 05 异步后台与流式 · 06 鉴权与安全 · 07 测试与项目骨架(本文) · 08 实战 HTTP↔MCP
行文:T4 项目篇 | 本篇方法:极度学习 + 科尔布循环 | 辅助:刻意练习
1. 成功标准(验收)
从空目录出发,最终应满足:
-
uvicorn app.main:app可启动,/docs可开 - 至少 1 个 router + service + schema
-
pytest绿,覆盖健康检查 + 1 条业务 API - 测试里用
dependency_overrides假 DB,不连真库 - 能用一段话讲清「请求进哪一层」
2. 推荐骨架(直接任务)
1 | fastapi-demo/ |
pyproject.toml(最小依赖)
1 | [project] |
安装:uv sync --extra dev(或 pip install -e ".[dev]")。
app/core/config.py
1 | from pydantic_settings import BaseSettings, SettingsConfigDict |
app/main.py
1 | from contextlib import asynccontextmanager |
app/routers/health.py
1 | from fastapi import APIRouter, Request |
3. 测试:TestClient + overrides
tests/conftest.py
1 | import pytest |
tests/test_items.py
1 | def test_get_item(client): |
TestClient 同步调用 ASGI 应用,不需要起真实 uvicorn 端口。
4. 科尔布四拍(建议写进学习笔记)
| 阶段 | 你做什么 | 本篇对应 |
|---|---|---|
| 具体经验 | 按骨架敲一遍,跑通 /health |
§2 |
| 反思 | 卡在哪?import 循环?override 忘 clear? | 记录 3 条 |
| 抽象 | 提炼规则:如「测试只 override 边界依赖」 | 见下 |
| 再实验 | 加一条 POST + 422 测试 | drills |
可复用三条规则:
- 应用工厂:
app在main.py单例,测试 import 同一实例才能 override。 - 假实现挂在 deps:repo 可内存实现,router 不改。
- 每个测试清理 overrides:放 fixture
yield后clear()。
5. 反馈回路
1 | # 运行 |
6. 费曼收束(一页纸提纲)
向同事讲解时覆盖:
- 请求进 router 之前经过了谁(中间件、Depends)?
- service 与 repository 各一句话职责?
- 测试为什么不用真数据库也能测 404?
7. 闪卡候选
| 正面 | 背面 |
|---|---|
| TestClient 测的是什么? | ASGI 应用,非 TCP 端口 |
| override 用完要? | dependency_overrides.clear() |
lifespan 在测试里跑吗? |
TestClient 上下文会触发 |
| 配置推荐? | pydantic-settings + .env |
小结
- 07 把 02–06 收成可运行仓库 + pytest 闭环。
- 下一篇 08 实战:HTTP 与 MCP 共进程:对接 MCP 系列,同一进程 REST + MCP。