Appearance
L01-11 集成测试与假模型
全局中心内容:AI 应用里真正要测的是「模型之外的所有代码」。 全局讲解主线:两种极端都错 → 三层金字塔 → 假模型怎么造 → 证明 mvn test 不花钱。
P1 · 产出页
中心内容:mvn test 跑绿,账单零新增。
页面内容
- 单元测试:假模型,秒级
- 集成测试:Testcontainers + 真数据库
- 冒烟测试:真实厂商,每天一次
讲解技巧
- 用钱开场:「跑一次测试几块钱,CI 一天几十次——最后你会关掉 CI」。这是真实的演进路径。
- 预告本节会验证「跑完测试账单没变化」。
时长:20s
P2 · 痛点页:两种极端都是错的
中心内容:全打真实模型会逼你关掉 CI。
页面内容
- 极端一:全真实 → 花钱、不稳定、没 Key 跑不了 → 关掉 CI → 回归保护归零
- 极端二:全 mock → mock 说返回 A,真实模型返回 B → 线上崩
讲解技巧
- 第一条要讲出因果链:不是「花钱」这么简单,是「花钱 → 有人提议关掉 → 回归保护归零」。这才是真实后果。
- 第二条点出本质:mock 只验证了你的假设,没验证模型的行为。
时长:2min 30s
P3 · 金字塔:三层各自解决什么
中心内容:每层解决不同的问题,不能互相替代。
页面内容
- 单元:假模型 → 编排/解析/分支,0 成本,每次提交
- 集成:Testcontainers + 假模型 → 持久化/Advisor 顺序/装配,0 成本
- 冒烟:真实厂商 → 模型是否仍遵循 Schema,几毛钱,每天一次
讲解技巧
- 给出一张三层表,横轴是成本、纵轴是频次。视觉上就能看出「越贵跑得越少」。
- 核心观点钉死:模型本身不在你的测试范围内,它是外部依赖——就像你不会在单测里验证 MySQL 的查询引擎。
时长:3min
P4 · 原理图:假模型怎么造
中心内容:ChatModel 是接口,实现 call() 就够了。
页面内容
interface ChatModel { ChatResponse call(Prompt); ChatOptions getDefaultOptions(); }- 给不同输入返回预设响应
- 能模拟正常、工具调用、脏输出、异常、慢响应
讲解技巧
- 把接口投屏,指出只有两个方法。学员会觉得「原来这么简单」。
- 强调最后三种最有价值:异常路径靠真实模型很难稳定复现,假模型让它变成常规可测路径。
时长:3min
P5 · 场景表:假模型能测什么
中心内容:脏输出、限流、超时,这些才最该被测试。
页面内容
- 正常回答 → 编排逻辑
- 触发工具调用 → 工具执行与结果回填
- 结构化脏输出 → Converter 清洗
- 超限/429/超时 → 压缩、重试、降级
讲解技巧
- 重点讲下三行:这些路径线上一定会走,但靠真实模型测不了。
- 提问留白:「你怎么让真实模型稳定地返回一段带代码块的脏 JSON?」——答不出来,这就是假模型的价值。
时长:2min 30s
P6 · 选型表:H2 vs Testcontainers
中心内容:用 H2 测 PostgreSQL,上线才发现建表失败。
页面内容
- H2:快,但方言差异测不到
- Testcontainers:慢一点,能测真实建表/索引/并发
- 差异点:JSONB、窗口函数、ON CONFLICT
讲解技巧
- 给一个真实事故:「H2 上全绿,上线建表失败,因为用了 JSONB」。具体故障比抽象对比有力。
- 诚实说明代价:需要本地 Docker,CI 上要配置。不要让环境问题阻断本地开发。
时长:2min
P7 · 编码:假模型实现
中心内容:两个工厂方法覆盖大部分场景。
页面内容
FakeChatModel.answering(text):固定回答FakeChatModel.echo():回显,便于断言call()里组装ChatResponse
讲解技巧
- 现场写一个 20 行的 FakeChatModel,让学员看到这件事有多轻。
- 强调设计目的:它的存在是为了让你能精确控制模型「返回什么」。
时长:4min
P8 · 编码:三个关键用例
中心内容:脏输出用例是本节精髓。
页面内容
- 输入原样传递 → echo 断言
- 带 ```json 的脏输出 → 验证清洗与反序列化
- 完全非法内容 → 验证走兜底不抛异常
讲解技巧
- 第二、第三个用例要强调:用真实模型反而测不了这些,因为你没法让它稳定地返回脏数据。
- 第三个的断言是
assertThat(t).isNotNull()——有兜底,这一行就是生产质量的证明。
时长:4min
P9 · 验证与小结
中心内容:跑之前记用量,跑完再看一次。
页面内容
mvn test无 Key 也能跑- 单元 < 10s,集成 < 60s
- 账单零新增
- 脏样本应来自线上真实失败案例
讲解技巧
- 验证「不花钱」的方法要现场做:打开厂商控制台记下用量,跑完再看。这个动作本身就是教学。
- 第一条避坑说透:一旦开了「单测依赖真实模型」的口子,用例会失控增长。
时长:2min
讲师备忘
| 项 | 内容 |
|---|---|
| 课前必做 | 确认 Docker 可用;预先拉取 postgres:16-alpine 镜像;准备线上脏输出样本 |
| 最容易超时处 | P6 的 H2 vs Testcontainers,容易展开讲方言细节——给三个例子就收 |
| 学员最常问 | 「冒烟测试多久跑一次?」答:每天一次,最多 5 个用例,maxTokens 设 50 |
| 现场备用 | Docker 起不来 → 跳过集成测试讲单元与冒烟,说明课后补 |