关于 qe-tdd-london-chicago
比较 London 与 Chicago 两种 TDD 学派,并说明混合使用方式。帮助开发者选择测试风格、遵循红绿重构循环,也提供 Agent 协作建议。
主要功能
- 01London 与 Chicago 风格比较
- 02红绿重构循环指导
- 03按代码类型选择风格
- 04模拟对象与状态验证示例
- 05Agent 协作建议
适用场景
- 01以测试优先方式启动功能开发
- 02选择模拟对象或真实协作者
- 03向团队讲解 TDD 实践
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill qe-tdd-london-chicago安装后在 Claude Code 中输入/qe-tdd-london-chicago确认已加载。
详细介绍
测试驱动开发:伦敦学派与芝加哥学派
<default_to_action> 在实施 TDD 或选择测试风格时:
- 识别代码类型:领域逻辑 → 芝加哥学派,外部依赖 → 伦敦学派
- 先编写失败的测试(Red 阶段)
- 实现最少的代码使测试通过(Green 阶段)
- 在保持测试通过的同时进行重构(Refactor 阶段)
- 为下一个功能重复此循环
快速选择风格:
- 纯函数/计算 → 芝加哥学派(使用真实对象,验证状态)
- 带依赖的控制器/服务 → 伦敦学派(使用模拟对象,验证交互)
- 值对象 → 芝加哥学派(测试最终状态)
- API 集成 → 伦敦学派(模拟外部服务)
- 实践中混合使用(控制器采用伦敦学派,领域逻辑采用芝加哥学派)
关键成功因素:
- 测试应驱动设计,而不只是验证设计
- 先让测试失败,确保它确实在测试某些内容
- 编写最少的代码,不实现测试范围之外的功能 </default_to_action>
快速参考卡
适用场景
- 以测试优先的方式开发新功能
- 为遗留代码添加测试覆盖并进行重构
- 向团队传授 TDD 实践
- 在模拟对象与真实对象之间做出选择
TDD 循环
| 阶段 | 操作 | 准则 |
|---|---|---|
| Red | 编写失败的测试 | 确认测试失败,并检查错误信息是否清晰 |
| Green | 编写最少的代码使测试通过 | 不添加额外功能,不进行重构 |
| Refactor | 改进结构 | 保持测试通过,不添加新功能 |
学派对比
| 方面 | 芝加哥学派(古典派) | 伦敦学派(模拟派) |
|---|---|---|
| 协作者 | 真实对象 | 模拟对象/存根 |
| 验证方式 | 状态(断言结果) | 交互(断言调用) |
| 隔离程度 | 较低(集成测试) | 较高(仅单元测试) |
| 重构 | 更容易 | 更困难(模拟对象容易失效) |
| 设计反馈 | 从使用中逐渐显现 | 从一开始就明确 |
Agent 协作
qe-test-generator:使用两种学派生成测试qe-test-implementer:实现最少的代码(Green)qe-test-refactorer:安全地进行重构(Refactor)
芝加哥学派(基于状态)
理念: 通过公共 API 测试可观察行为。让测试贴近使用者的使用方式。
// State verification - test final outcome
describe('Order', () => {
it('calculates total with tax', () => {
const order = new Order();
order.addItem(new Product('Widget', 10.00), 2);
order.addItem(new Product('Gadget', 15.00), 1);
expect(order.totalWithTax(0.10)).toBe(38.50);
});
});
芝加哥学派的优势场景:
- 状态明确的领域逻辑
- 算法与计算
- 值对象(
Money、Email) - 简单的协作关系
- 学习新领域
伦敦学派(基于模拟)
理念: 单独测试每个单元。关注对象之间如何协作。
// Interaction verification - test method calls
describe('Order', () => {
it('delegates tax calculation', () => {
const taxCalculator = {
calculateTax: jest.fn().mockReturnValue(3.50)
};
const order = new Order(taxCalculator);
order.addItem({ price: 10 }, 2);
order.totalWithTax();
expect(taxCalculator.calculateTax).toHaveBeenCalledWith(20.00);
});
});
伦敦学派的优势场景:
- 外部集成(数据库、API)
- 带有副作用的命令模式
- 复杂工作流
- 耗时操作(网络、I/O)
混合方法(推荐)
// London for controller (external deps)
describe('OrderController', () => {
it('creates order and sends confirmation', async () => {
const orderService = { create: jest.fn().mockResolvedValue({ id: 123 }) };
const emailService = { send: jest.fn() };
const controller = new OrderController(orderService, emailService);
await controller.placeOrder(orderData);
expect(orderService.create).toHaveBeenCalledWith(orderData);
expect(emailService.send).toHaveBeenCalled();
});
});
// Chicago for domain logic
describe('OrderService', () => {
it('applies discount when threshold met', () => {
const service = new OrderService();
const order = service.create({ items: [...], total: 150 });
expect(order.discount).toBe(15); // 10% off > $100
});
});
常见陷阱
❌ 过度使用模拟对象(伦敦学派)
// BAD - mocking everything
const product = { getName: jest.fn(), getPrice: jest.fn() };
更好的做法: 仅模拟外部依赖。
❌ 模拟内部实现
// BAD - testing private methods
expect(order._calculateSubtotal).toHaveBeenCalled();
更好的做法: 只测试公共行为。
❌ 测试痛点 = 设计痛点
- 需要很多模拟对象?→ 依赖过多
- 难以设置?→ 构造函数承担了太多职责
- 不连接数据库就无法测试?→ 存在耦合问题
借助 Agent 进行 TDD
// Agent generates tests in both schools
await Task("Generate Tests", {
style: 'chicago', // or 'london'
target: 'src/domain/Order.ts',
focus: 'state-verification' // or 'collaboration-patterns'
}, "qe-test-generator");
// Agent-human ping-pong TDD
// Human writes test concept
const testIdea = "Order applies 10% discount when total > $100";
// Agent generates formal failing test (Red)
await Task("Create Failing Test", testIdea, "qe-test-generator");
// Human writes minimal code (Green)
// Agent suggests refactorings
await Task("Suggest Refactorings", { preserveTests: true }, "qe-test-refactorer");
Agent 协作提示
记忆命名空间
aqe/tdd/
├── test-plan/* - TDD session plans
├── red-phase/* - Failing tests generated
├── green-phase/* - Implementation code
└── refactor-phase/* - Refactoring suggestions
Fleet 协作
const tddFleet = await FleetManager.coordinate({
workflow: 'red-green-refactor',
agents: {
testGenerator: 'qe-test-generator',
testExecutor: 'qe-test-executor',
qualityAnalyzer: 'qe-quality-analyzer'
},
mode: 'sequential'
});
相关技能
- agentic-quality-engineering - 通过 Agent 协作进行 TDD
- refactoring-patterns - Refactor 阶段的技巧
- api-testing-patterns - 用于 API 测试的伦敦学派
请记住
芝加哥学派: 测试状态,使用真实对象,自由重构
伦敦学派: 测试交互,模拟依赖,先设计接口
两者皆可: 先编写测试,让测试通过,再进行重构
两种学派都没有绝对的“正确”之选。根据具体情况选择,按需混合使用。目标是编写设计良好、经过测试的代码。
使用 Agent: Agent 擅长生成测试、验证 Green 阶段以及提出重构建议。借助 Agent 保持 TDD 纪律,让人类专注于设计决策。
评论
支持 Markdown