OpenSpec、Superpowers、SDD、TDD、BDD:一套更稳的研发方法
很多团队在讨论研发方法时,容易把几个概念混在一起:OpenSpec、Superpowers、SDD、TDD、BDD。表面上它们都和“提高开发质量”有关,但如果不把角色分清楚,最后往往只剩下一句口号:要规范、要测试、要先设计。
真正有价值的问题不是“这些词是什么意思”,而是:
- 它们分别解决什么问题
- 它们为什么真的能起作用
- 在一条真实研发链路里,它们应该怎么配合
这篇文章尝试把这几件事讲清楚。
先说结论:它们不是同一层东西
如果只用一句话概括,可以这样理解:
OpenSpec = 用工件约束决策
Superpowers = 用流程约束执行
SDD = 先定义规格,再开始实现
TDD = 先写测试,再推动代码落地
BDD = 先描述行为,再对齐业务规则它们并不是互相替代的关系,而是分布在不同层级。
BDD更偏业务行为层SDD更偏需求和设计层TDD更偏编码和验证层OpenSpec是SDD的落地载体Superpowers是一组把工程流程前置约束起来的执行机制
所以真正合理的关系不是“TDD 还是 SDD 二选一”,而是:
先用 BDD 说清行为
再用 SDD / OpenSpec 说清规格和边界
最后在实现阶段按需要使用 TDD 落地
同时用 Superpowers 管住整个执行过程OpenSpec 解决的不是编码问题,而是“定义问题”
很多项目并不是死在“不会写代码”,而是死在“还没定义清楚就开始写”。
最常见的情况是这样:
一句需求
-> 开始改代码
-> 改到一半才发现边界不清
-> 联调时发现影响面比预想大
-> 文档、实现、测试三边失配OpenSpec 要解决的就是这个问题。
它的核心机制不是“多写文档”,而是把关键决策显式化成一组工件。典型工件通常包括:
proposal.md:为什么做、范围是什么design.md:怎么做、关键方案和边界是什么tasks.md:按什么顺序落地、拆成哪些任务
这件事为什么有用?因为它把原本藏在脑子里、会议里、聊天记录里的决策,变成了可检查、可追溯、可续做的内容。
也就是说,代码不再直接从一句模糊需求长出来,而是从明确的规格工件长出来。
这本质上就是 Spec-Driven Development,也就是 SDD。
Superpowers 解决的是“人和流程容易失控”
如果说 OpenSpec 更偏“做什么”,那 Superpowers 更偏“怎么做”。
它不是一个单独的方法,而是一组前置工作流。它的目标不是让人显得专业,而是把最容易犯错的工程行为拦在入口。
比如:
- 新功能不是直接写,而是先
brainstorming - Bug 不是先猜修复,而是先
systematic-debugging - 实现不是随手改,而是尽量通过
test-driven-development - 完成不是主观宣称,而是先做
verification-before-completion
这套机制真正起作用的原因,在于它改变了默认路径。
默认路径通常是:
看到需求 -> 开写
看到报错 -> 开猜
改完代码 -> 说修好了而 Superpowers 强制把它变成:
看到需求 -> 先澄清
看到问题 -> 先定位根因
开始实现 -> 先建立验证方式
准备交付 -> 先跑验证这不是“更聪明”,而是“更不容易乱来”。
SDD 才是上层核心,TDD 只是实现阶段的重要手段
很多人一聊工程方法,注意力就会全部落到 TDD 上,好像只要先写测试,整个研发流程就自动变稳了。
这其实是把问题看窄了。
TDD 很重要,但它解决的是实现阶段的问题,比如:
- 代码是否围绕可验证行为展开
- 改动有没有回归保护
- 接口行为是否被测试约束
但它解决不了这些更上游的问题:
- 需求到底是什么
- 哪些在范围内,哪些不在
- 为什么选这个方案,不选另一个方案
- 影响的是一个模块,还是多个仓库
这些问题,靠的是 SDD,也就是先把规格定义清楚,再进入实现。
所以如果非要问“这套方法的核心更像 TDD 还是 SDD”,我的判断是:
上层核心是 SDD
TDD 是实现阶段的局部强约束这也是为什么 OpenSpec 这类东西通常要先于编码存在。
BDD 又是什么,它和 TDD 的边界在哪里
BDD 是 Behavior-Driven Development,行为驱动开发。
它关注的不是内部类怎么拆、数据库怎么落,而是系统对外必须表现出什么行为。最常见的表达方式是:
Given 某个前置条件
When 发生某个操作
Then 应该得到某个结果比如订单取消场景:
Feature: 取消订单
Scenario: 用户取消待支付订单
Given 存在一个订单,状态为待支付
And 当前操作人是下单用户本人
When 用户发起取消订单
Then 订单状态应变为已取消
And 系统记录取消时间
And 系统记录取消原因为用户主动取消
Scenario: 用户取消已支付订单
Given 存在一个订单,状态为已支付
And 当前操作人是下单用户本人
When 用户发起取消订单
Then 操作应失败
And 系统提示“当前订单状态不允许取消”
And 订单状态保持不变这段描述有一个很大的价值:产品、测试、开发都能读懂,而且读完之后更容易对齐。
所以:
BDD更像是在定义业务行为和验收标准TDD更像是在用测试约束实现过程
可以粗暴理解成:
BDD 负责说清楚“系统应该怎么表现”
TDD 负责保证“代码真的这样表现”一条完整链路里,它们怎么配合
如果把一个真实需求从进入到交付展开,大概会是这样一条链路:
需求进入
-> BDD:先定义关键业务行为
-> OpenSpec / SDD:再形成 proposal / design / tasks
-> Superpowers:按合适流程推进探索、排障、实现、验证
-> TDD:在实现阶段用测试驱动关键代码
-> 验证完成
-> 交付这几个东西放在一起,角色就很清楚了。
第一层:BDD 负责行为对齐
它回答的是:
- 在什么前提下允许做这件事
- 触发后系统必须产生什么结果
- 失败时系统应该如何反馈
如果这层没定义清楚,后面写出来的测试可能也只是“验证了错误的东西”。
第二层:OpenSpec / SDD 负责规格落地
它回答的是:
- 这次改动的目标是什么
- 影响哪些模块和接口
- 为什么这样设计
- 哪些内容不在当前范围
这层让“行为”进一步变成“工程可执行的设计和任务”。
第三层:Superpowers 负责过程约束
它回答的是:
- 现在这类任务应该先按什么流程处理
- 是继续探索,还是已经可以实现
- 是根因没查清,还是已经可以改代码
- 是真验证过了,还是只是主观觉得好了
这层防的是执行过程跑偏。
第四层:TDD 负责实现压实
它回答的是:
- 代码是不是围绕可验证行为收敛
- 改动会不会引入回归
- 关键业务规则有没有被稳定保护
这层防的是实现阶段的漂移和脆弱性。
为什么这套组合在多仓项目里更有价值
在单仓、小系统里,很多问题还可以靠人脑兜住。
但在多仓、历史包袱重、领域逻辑复杂的项目里,靠“感觉”做事的成本会快速放大。
比如一个典型的 Java 多模块或多仓工作区,经常会同时存在:
- 后端服务仓
- 对外 API 仓
- 管理端前端仓
- C 端前端仓
- 配套脚本和文档仓
这时候最容易出的问题不是“不会写代码”,而是:
- 改动边界不清
- 接口变了但上下游没同步
- 文档没更新
- 只测了本仓,没考虑联动影响
在这种环境下:
BDD帮你先固定业务规则OpenSpec帮你固定影响范围和设计决策Superpowers帮你限制执行动作不要失控TDD帮你给实现加上稳定保护
也就是说,项目越复杂,这套组合越不是形式主义,反而越像一套必要的减灾机制。
一个更具体的案例:取消订单功能
假设现在来了一个需求:
“支持用户取消待支付订单,但已支付订单不允许直接取消。”
没有这套方法时,很多团队会这样推进:
收到需求
-> 开始改 Controller / Service
-> 改 DTO
-> 写两个 if 判断
-> 联调时才发现错误码、提示文案、审计字段都没统一
-> 测试补不全而如果把这几个方法叠起来,路径会变成这样:
第一步:先用 BDD 定义行为
- 待支付订单允许取消
- 已支付订单禁止取消
- 只能本人取消
- 成功时记录取消时间和原因
- 失败时返回明确提示,且状态不变
第二步:再用 OpenSpec 固化规格
在 proposal.md 里明确:
- 为什么做
- 本次仅支持待支付取消
- 不涉及退款链路改造
在 design.md 里明确:
- 涉及哪些接口
- 状态校验放在哪层
- 审计字段怎么落
- 错误码和提示文案怎么统一
在 tasks.md 里拆成:
- API 调整
- Service 实现
- 单元测试
- 联调验证
- 文档更新
第三步:实现阶段再用 TDD 压实
测试命名可能像这样:
shouldCancelOrderWhenStatusIsPendingPayment();
shouldRejectCancellationWhenOrderIsPaid();
shouldRejectCancellationWhenOperatorIsNotOrderOwner();这时测试就不只是“补一个流程”,而是在给前面定义好的业务规则做落地保护。
第四步:交付前用 Superpowers 强制验证
比如:
- 先确认根因和边界是否清楚
- 先运行最小相关测试集
- 再跑模块级校验
- 最后回看文档、接口、任务状态是否一致
这样整条链路才真正闭环。
它为什么不是形式主义
很多人第一次接触这种方法,会本能地觉得“步骤变多了”。
但步骤变多,不等于形式主义。关键要看它拦住了什么成本。
这套方法真正减少的是三类高成本错误:
- 方向错了,写完才发现需求理解错
- 范围漏了,联调时才发现影响不止一个模块
- 验证弱了,改完就说好了,结果线上回归
如果一个流程只是增加文档,没有减少返工,那它确实是负担。
但如果一个流程能把返工、回归、沟通偏差明显前置,那它本质上是在节省总成本。
所以判断它值不值得用,不能只看“前面多写了多少”,而要看“后面少返了多少”。
最后总结
把这几个概念拆开之后,整个结构其实并不复杂:
BDD:定义行为
SDD:定义规格
OpenSpec:承载规格工件
Superpowers:约束执行流程
TDD:压实实现质量它们各自负责不同的事,但组合起来,刚好覆盖了一条研发链路里最容易失控的几个点:
- 需求没对齐
- 边界没说清
- 执行太随意
- 测试太薄弱
- 验证不完整
如果只让我保留一句最重要的话,那就是:
先用 BDD 和 SDD 管住方向
再用 Superpowers 和 TDD 管住落地真正稳定的交付,从来不是“写代码更快”,而是“在正确方向上,把代码写对、测对、交付对”。