mcpField
Q
qe-tdd-london-chicago

qe-tdd-london-chicago

github.com/proffesor-for-testing测试与质量51980 次安装今天更新
代码仓库

关于 qe-tdd-london-chicago

比较 London 与 Chicago 两种 TDD 学派,并说明混合使用方式。帮助开发者选择测试风格、遵循红绿重构循环,也提供 Agent 协作建议。

主要功能

  1. 01London 与 Chicago 风格比较
  2. 02红绿重构循环指导
  3. 03按代码类型选择风格
  4. 04模拟对象与状态验证示例
  5. 05Agent 协作建议

适用场景

  1. 01以测试优先方式启动功能开发
  2. 02选择模拟对象或真实协作者
  3. 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 或选择测试风格时:

  1. 识别代码类型:领域逻辑 → 芝加哥学派,外部依赖 → 伦敦学派
  2. 先编写失败的测试(Red 阶段)
  3. 实现最少的代码使测试通过(Green 阶段)
  4. 在保持测试通过的同时进行重构(Refactor 阶段)
  5. 为下一个功能重复此循环

快速选择风格:

  • 纯函数/计算 → 芝加哥学派(使用真实对象,验证状态)
  • 带依赖的控制器/服务 → 伦敦学派(使用模拟对象,验证交互)
  • 值对象 → 芝加哥学派(测试最终状态)
  • 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'
});

相关技能


请记住

芝加哥学派: 测试状态,使用真实对象,自由重构
伦敦学派: 测试交互,模拟依赖,先设计接口
两者皆可: 先编写测试,让测试通过,再进行重构

两种学派都没有绝对的“正确”之选。根据具体情况选择,按需混合使用。目标是编写设计良好、经过测试的代码。

使用 Agent: Agent 擅长生成测试、验证 Green 阶段以及提出重构建议。借助 Agent 保持 TDD 纪律,让人类专注于设计决策。

评论

支持 Markdown