为什么 AI 时代反而需要 SDD 和 TDD?

12/07/2026

为什么 AI 时代反而需要 SDD 和 TDD?

AI Coding 时代,SDD帮助我们明确“开发什么”,TDD帮助我们验证“是否正确”。本文结合 OpenSpec、真实项目案例和个人理解,探索两者如何结合,构建更高效、更可靠的软件开发流程。

#ai #SDD #TDD

最近在学习 AI Coding 相关的开发流程时,我接触到了两个之前没有深入理解的概念:

  • SDD(Specification Driven Development,规范驱动开发)
  • TDD(Test Driven Development,测试驱动开发)

最开始接触 SDD 的时候,我其实比较容易理解。

因为它和传统的软件开发流程非常接近:

需求分析
↓
产品设计
↓
UI设计
↓
技术方案
↓
前端/后端开发
↓
测试
↓
上线

但是 TDD 一开始让我非常困惑。

为什么测试要提前写?

测试不是应该在代码完成之后,用来验证代码有没有问题吗?

而且如果测试用例先写,那开发之前怎么可能考虑完整所有情况?

带着这些疑问,我开始深入了解 TDD 和 SDD,并结合 AI Coding 时代的软件开发方式重新思考这两个概念。

这篇文章记录一下我的理解过程。

一、为什么现在重新关注 SDD 和 TDD?

在传统软件开发过程中,通常是:

需求
↓
开发人员理解需求
↓
设计方案
↓
编写代码
↓
测试
↓
上线

这种方式在过去几十年中非常成熟。

但是随着软件复杂度提升,以及 AI Coding 工具出现,我发现一个新的问题:

> 现在写代码越来越容易,但是确定“应该写什么代码”越来越困难。

以前:开发人员需要花大量时间写代码。

现在:AI 可以快速生成大量代码。例如:

告诉 AI:

帮我开发一个博客系统

AI 很快可以生成:

  • 页面
  • API
  • 数据库模型
  • 组件代码

但是 AI 不知道:

  • 这是个人博客还是商业博客?
  • 是否需要用户体系?
  • 是否需要权限?
  • 是否需要评论?
  • 技术架构是什么?
  • 哪些功能是必须的?

最终可能生成一个:

> 看起来完整,但是并不是我真正想要的系统。

所以 AI Coding 时代,最大的挑战逐渐从:“如何写代码” 变成:“如何准确描述我要构建什么”。

这也是 SDD 重新受到关注的重要原因。

二、我对 SDD 的理解

SDD 可以理解为:

> 在真正开始开发之前,通过 Specification(规范)明确系统应该是什么样子。

它解决的问题是:

> 我们到底要开发什么?

传统开发:

需求文档
↓
开发

而 SDD:

需求
↓
Specification
↓
设计
↓
任务拆分
↓
开发

三、通过一个真实项目理解 SDD

假设我要开发一个: 打牌记账微信小程序

需求:

> 用户创建牌局房间,邀请朋友加入,然后记录每个人输赢,最终自动结算。

如果直接开发:可能马上开始:

创建房间页面
↓
房间接口
↓
数据库
↓
结算逻辑

但是开发过程中会不断遇到问题:

  • 房间有没有人数限制?
  • 房主退出怎么办?
  • 输赢如何计算?
  • 是否支持重新结算?
  • 是否保存历史记录?

这些问题如果没有提前明确,开发过程会不断返工。

使用 SDD 后

首先拆 Specification。例如:

requirements.md

描述业务规则:

功能:
创建牌局房间

用户输入:
- 房间名称

系统返回:
- 房间ID

规则:
- 创建者拥有管理权限
- 一个房间最多10人
- 房间创建后可以邀请成员加入

design.md

描述技术设计:

系统架构:

微信小程序
↓
NestJS API
↓
MySQL

数据模型:

Room
id
name
creatorId
status
createdAt

接口:

POST /rooms

tasks.md

拆分开发任务:

Task1:
创建Room数据库表

Task2:
实现createRoom Service

Task3:
实现创建房间接口

Task4:
增加权限校验

这样开发人员或者 AI Agent 才知道:

  • 为什么做
  • 做什么
  • 怎么拆分

所以:

> SDD解决的是“开发方向问题”。

四、为什么 AI Coding 时代更加需要 SDD?

以前:

需求
↓
人理解需求
↓
人写代码

现在:

需求
↓
Specification
↓
AI Agent
↓
生成代码

AI 最大的问题不是不会写代码。

而是不知道:

> 你真正想要什么。

Specification 就成为:

人与 AI 之间的沟通层。

它把人的想法转换成 AI 可以执行的约束。

五、我最开始不理解 TDD 的地方

相比 SDD,TDD 一开始让我更加疑惑。

传统开发:

写代码
↓
运行
↓
发现问题
↓
修改

而 TDD:

写测试
↓
测试失败
↓
写代码
↓
测试通过
↓
重构

我的第一个疑问:

> 为什么要反过来?

后来我理解:TDD 并不是:

“提前写很多测试代码”。

它真正表达的是:

> 先定义代码应该具备什么行为,再实现这个行为。

六、通过一个真实案例理解 TDD

还是以:创建房间功能为例。

SDD 已经拆出来:

Task:
实现 createRoom Service

普通开发方式

开发人员可能直接:

async createRoom(dto){

 return repository.save(dto)

}

然后测试发现问题:

  • 房间名称为空也可以创建
  • 返回格式不符合要求
  • 缺少权限判断

于是:

写代码
↓
发现问题
↓
修改代码

TDD 的实际过程:红 → 绿 → 重构

TDD 通常遵循:

Red
↓
Green
↓
Refactor

第一步:Red

先写测试。例如:

test(
"创建房间应该成功",
async()=>{

const room =
await service.createRoom({
 name:"周末麻将"
})


expect(room.name)
.toBe("周末麻将")

})

运行:

FAIL

失败是正常的。因为功能还没有实现。

第二步:Green

实现最简单代码:

async createRoom(dto){

return {
      name:dto.name
}}

再次运行:

PASS

第三步:Refactor

现在代码可以优化。

例如:拆分:

RoomService
↓
RoomValidator
↓
RoomRepository

只要测试通过:就可以放心重构。

八、TDD最大的价值:让重构变得安全

这是我后来认为 TDD 最重要的价值。

很多人认为:

> TDD只是为了减少 Bug。

但是实际上:

> TDD 最大的价值,是让未来修改代码变得更加安全。

例如:

第一版:

function calculateScore(){

}

半年后:业务越来越复杂:

  • 不同牌局规则
  • VIP积分
  • 活动奖励
  • 特殊计算方式

代码可能变成:

calculateScore(){

if(){
}

if(){
}

if(){
}

}

这时候开发人员想重构。拆成:

ScoreCalculator

RuleEngine

BonusCalculator

如果没有测试:只能依靠人工验证。风险很高。 但是有 TDD:

修改代码
↓
运行测试
↓
测试通过
↓
确认行为没有改变
↓
安全上线

所以:

> 测试不是限制重构,而是保护重构。

九、TDD 的测试能覆盖全部情况吗?

这是我最开始最大的疑问。如果测试不能考虑全面:

> 那 TDD 有意义吗?

后来理解:

> TDD 不要求一次性预测未来所有情况。

真实项目中:

测试会随着需求变化不断增加。

例如:

第一版本:

创建房间

记录输赢

结算

测试:

创建房间成功

金额计算正确

上线之后:

用户提出:

> 玩家中途退出怎么办?

那么增加:

玩家退出重新计算

对应增加测试。所以测试不是: 预测未来。

而是:

记录当前系统应该具备的行为。

十、为什么 TDD 会导致更好的架构设计?

这是 TDD 最容易被忽略的价值。原因:

> 难测试的代码,通常也是难维护的代码。

例如:

一个订单服务:

class OrderService{

createOrder(){

    查询用户
    查询商品
    检查库存
    计算价格
    创建订单
    扣库存
    发送邮件
}}

测试这个方法,需要准备:

  • 数据库
  • 用户数据
  • 商品数据
  • 库存服务
  • 邮件服务

测试非常困难。

这说明:代码职责太多,耦合严重。

于是拆分:

OrderService
↓
InventoryService
PricingService
NotificationService

每个模块:

  • 职责单一
  • 可以独立测试
  • 更容易维护

所以 TDD 会推动:

  • 单一职责原则
  • 低耦合设计
  • 面向接口设计
  • 模块化架构

十一、SDD 和 TDD 如何结合?

如果使用 OpenSpec:生成:

proposal
design
tasks

是不是直接 apply 执行?我的理解:不是简单执行。

更合理流程:

需求
↓
OpenSpec
↓
proposal
↓
design
↓
tasks
↓
选择Task
↓
编写测试
↓
实现代码
↓
运行测试
↓
重构
↓
Task完成

十二、OpenSpec 怎么知道执行哪些测试?

这里容易产生误解。

> OpenSpec 本身不知道。

因为:

> SDD 和 TDD 解决的问题不同。

SDD:

我要做什么

TDD:

如何证明做对了

两者通过工程规范连接。

例如:

团队规定:每个 Task, 必须包含:

Implementation

Test

Validation

例如:

Task:
实现createRoom API

Implementation:
创建接口

Test:
创建成功
空名称失败

Validation:
npm test

十三、TDD实际使用哪些工具?

TDD不是一个工具。而是一种开发方法。常见测试工具:

  • Jest
  • Vitest
  • React Testing Library

十四、AI Agent 为什么更加需要 TDD?

AI 写代码最大的风险:不是不会写。而是:

  • 理解错误
  • 修改错误文件
  • 过度实现
  • 破坏已有逻辑

TDD提供一个反馈闭环:

AI生成代码
↓
运行测试
↓
测试失败
↓
AI根据错误修复
↓
测试通过

测试成为:AI Agent 的自动反馈机制。

十五、我现在对 SDD 和 TDD 的最终理解

如果把开发软件比作建房子:

SDD

类似:建筑设计图。决定:

我要建什么房子?

房间如何布局?

TDD

类似:施工验收标准。保证:

每个结构符合要求。

所以:

SDD解决:

> 我们是不是在开发正确的东西?

TDD解决:

> 我们开发出来的东西是不是正确?

十六、总结

以前的软件开发:

人理解需求
↓
人设计方案
↓
人写代码
↓
人测试

AI Coding 时代:

人定义 Specification
↓
AI生成任务
↓
AI编写代码
↓
TDD验证

人的角色正在从:

> 代码生产者

转变为:

> 系统设计者和约束制定者。

最终我的理解:

> SDD 是 AI 时代解决“方向问题”的方法。

> TDD 是 AI 时代解决“质量问题”的方法。

两者结合,会成为未来 AI 软件开发的重要工作流。

(以上内容是我总结出来的并不代表正确,仅供参考,如有问题可联系我纠正)