外向内TDD与六边形架构技能 growing-outside-in-systems

本技能提供了一套完整的软件工程方法论,专注于使用外向内测试驱动开发与六边形架构构建高质量后端系统。核心内容包括:浮现式设计工作流、内存假对象替代模拟对象、亚秒级测试反馈、延迟I/O实现、行走骨架模式等。适用于TDD实践者、软件架构师、后端开发人员,帮助团队构建可测试、可维护、松耦合的软件系统。关键词:外向内TDD、六边形架构、端口适配器模式、浮现式设计、验收测试、组件测试、内存假对象、契约测试、行走骨架、红绿重构、领域驱动设计、软件架构、测试驱动开发、后端开发、敏捷开发。

后端开发 0 次安装 0 次浏览 更新于 2/23/2026

name: growing-outside-in-systems description: > 使用外向内测试驱动开发与六边形架构驱动功能开发。 设计通过内联代码、内存假对象、接口提取和延迟I/O逐步浮现。 适用于构建功能、编写测试或构建后端服务时使用。 触发词:TDD、外向内、六边形架构、端口与适配器、浮现式设计、 验收测试、组件测试、行走骨架、内存假对象、 组件、契约测试、适配器、快速测试、亚秒级反馈。 语言无关(Go、Rust、Python、TypeScript、Java、C#)。 allowed-tools: Read Glob Grep WebFetch metadata: author: giladw version: “1.0.0” category: backend-development backlog-id: SK-GOIS-001

STARTER_CHARACTER = 🔴🟢

外向内TDD与六边形架构

通过从外向内驱动设计来构建功能。每个功能都从一个失败的验收测试开始。设计通过严格的红-绿-重构循环逐步浮现。基础设施延迟到领域API被验证后才实现。

与使用模拟对象的自内向外TDD不同,这种方法在边界测试行为——而非实现细节——使测试套件天生支持重构。参见methodology.md

关于贯穿始终的规范术语,参见references/glossary.md


两个循环

外循环(验收测试): 在服务/系统边界编写一个失败的范围测试。该测试使用内存适配器跨限界上下文进行集成测试。它定义了“完成”的标准。

内循环(红-绿-重构): 在限界上下文内循环以使外部测试通过。仅当需要实现验收测试要求时才进入此循环。

每个功能都从外向内开始。验收测试驱动整个过程。


测试优先级

验收测试和组件测试是主要工具。单元测试是例外。

  • 验收测试 — 服务/系统边界,进程内,内存适配器;作为规范阅读
  • 组件测试 — 单个限界上下文;通过内存适配器驱动内部模块设计
  • 单元测试 — 仅例外情况:良好隔离、真正复杂、算法或组合逻辑

完整定义、测试矩阵和契约测试模式参见testing-strategy.md


测试矩阵

快速 慢速
大范围 验收与组件 — 日常使用 E2E — 最小化
小范围 单元 — 谨慎使用 契约 — 仅CI

亚秒级反馈是不可妥协的。 如果测试需要几秒钟,团队就会停止重构,系统就会衰退。


浮现式设计工作流

在每个限界上下文中严格遵循此顺序:

  1. 内联 — 在业务代码中朴素地实现逻辑;使用局部变量、列表、映射;无抽象
  2. 内存适配器 — 一旦行为被验证,将逻辑提取到专用的内存适配器实现中
  3. 接口 — 从实际浮现的内容中提取适配器接口(而非理论猜测)
    • 检查点: 接口中的所有类型必须位于六边形内部
    • I/O检查点: 如果没有I/O且不运行在进程外 → 保持在六边形内部;不要创建端口
  4. 延迟I/O — 仅在API成熟后实现真正的适配器(数据库、网络、文件系统)
  5. 重构六边形内部的内联代码

此顺序是不可妥协的。 每个步骤收集关于适配器实际需求的证据。详细原理和行走骨架参见methodology.md


六边形架构

领域层是中心。所有I/O都位于边界后的适配器接口之后。

依赖规则: 基础设施(适配器) → 应用(端口) → 领域(外层依赖内层,绝不反向)

I/O分类规则: 如果不执行I/O且不运行在进程外 → 属于六边形内部;否则 → 适配器。

端口引用的类型必须位于六边形内部。 如果端口签名引用适配器层中的类型,六边形就向外依赖——这是违规。

命名:

  • 端口:For[某事物](例如:ForCalculatingTaxesForGettingTaxRates
  • 适配器:[某事物]Adapter(例如:WebUIAdapterSQLDatabaseAdapter

完整文件夹结构、私有/公共六边形拆分、跨六边形依赖规则、适配器设计模式和测试接缝参见folder-structure.md


内存假对象,而非模拟对象

对所有适配器边界使用内存假对象。领域级测试绝不使用模拟对象或桩对象。

假对象是基于简单数据结构(映射、列表)的真实实现。它们具有实际行为。模拟对象仅验证调用序列——它们将测试耦合到实现细节,每次重构都会破坏测试。

契约测试验证真实适配器与假对象的行为匹配。参见testing-strategy.md


行走骨架

对于新项目或主要新组件:首先构建一个最小的端到端实现,以提前支付集成成本。一旦建立,转向浮现式设计工作流。参见methodology.md


组合根(配置器)

在启动时连接所有适配器接口。用于两种上下文:

  • 生产: 真实适配器实现(数据库、网络、文件系统)
  • 测试: 内存适配器实现 → 快速、确定性的测试工具

相同的业务逻辑在两种上下文中运行——仅适配器不同。


功能实现顺序

  1. 编写失败的验收测试 — 定义“完成”
  2. 进入内循环 — 红-绿-重构
  3. 遵循浮现式设计顺序 — 内联 → 内存 → 接口 → 延迟I/O
  4. 如果需要,添加组件测试 — 当限界上下文变得复杂时
  5. 仅在合理时添加单元测试 — 复杂算法、组合逻辑
  6. 最后实现真实适配器 — 通过与内存假对象的契约测试进行验证

倾听测试

编写测试困难是设计信号,而非技能问题:

  • 难以设置 → 依赖过多;拆分或重新思考适配器边界
  • 难以断言 → API隐藏或纠缠了调用者需要的信息
  • 脆弱,重构时破坏 → 测试实现细节;升级到组件/验收测试
  • 缓慢 → 访问真实I/O;找到缺失的适配器边界

不要与测试对抗。重塑代码直到测试易于编写。


参考文档

  • glossary.md — 规范术语
  • folder-structure.md — 文件夹结构、私有/公共六边形、跨六边形规则、适配器模式、测试接缝
  • testing-strategy.md — 完整测试矩阵、验收/组件测试规则、契约测试模式
  • methodology.md — 为什么选择外向内而非常规TDD、行走骨架、浮现式设计深度解析、倾听测试、反模式

来源