AI 开发范式:SDD + TDD 融合实践指南
—— 从零构建前端系统的实战演练
分享主题:AI 时代的开发范式革新
适用人群:前端工程师、全栈开发者、技术负责人
核心理念:规范先行 (SDD) → 测试驱动 (TDD) → 精准编码 (Coding)
案例背景:从零开发一个“任务管理看板(Task Board)”前端系统
📑 目录 / 提纲
-
背景:AI 时代的新挑战与新机遇
-
核心概念与融合逻辑
- 2.1 SDD:规范驱动开发
- 2.2 TDD:测试驱动开发
- 2.3 融合工作流:标准执行顺序
-
实战案例:从零开发前端任务看板系统
- 3.1 阶段一:SDD 规范定义(蓝图绘制)
- 3.2 阶段二:TDD 测试先行(考卷生成)
- 3.3 阶段三:Coding 精准实现(答题过关)
- 3.4 阶段四:集成与持续迭代
-
实施流程详解:红 - 绿 - 重构的 AI 增强版
-
工具链推荐
-
最佳实践与团队落地建议
-
总结与行动路线图
-
附录:快速参考卡片
1. 背景:AI 时代的新挑战与新机遇
在 AI 编程助手普及的今天,代码生成的效率得到了数量级的提升。然而,单纯依赖 AI 生成代码也带来了新的工程挑战:
- “氛围编码”(Vibe Coding)风险:需求描述模糊时,AI 生成的代码往往“看起来能跑”,但缺乏严谨的边界处理和业务逻辑一致性。
- 质量黑盒:自动生成的代码若缺乏即时验证,容易隐藏状态管理混乱、接口不一致等深层隐患。
- 维护债务:代码与文档脱节,后期重构成本高,尤其是当前端交互逻辑日益复杂时。
解决方案:引入 SDD(Specification-Driven Development,规范驱动开发) 与 TDD(Test-Driven Development,测试驱动开发) 的深度融合范式。
本分享将通过“从零开发一个前端任务看板系统”的完整案例,演示如何建立 “规范 -> 测试 -> 代码” 的标准化作业流程,实现人机协同的高质量交付。
2. 核心概念与融合逻辑
2.1 SDD:规范驱动开发
定义:
SDD 是一种以结构化规范文档为唯一真理来源(Single Source of Truth)的开发方法论。在编写任何可执行代码之前,首先用机器可读的格式(如 Markdown + YAML/JSON)精确定义系统的数据结构、接口契约、业务规则和验收标准。
核心价值:
- 消除歧义:将模糊的自然语言需求转化为精确的逻辑描述。
- AI 导航图:为 AI 提供清晰的上下文约束,防止“幻觉”和过度设计。
- 活文档:规范文档随代码演进,始终保持一致。
2.2 TDD:测试驱动开发
定义:
TDD 是一种以测试用例驱动功能实现的方法论。严格遵循 "红 - 绿 - 重构" (Red-Green-Refactor) 循环:先写一个失败的测试,再写最少的代码让测试通过,最后重构优化。
核心价值:
- 行为锁定:测试用例即是对规范的可执行解释。
- 即时反馈:每一行代码的产出都有明确的验证目标。
- 安全网:为后续的重构和迭代提供信心保障。
2.3 融合工作流:标准执行顺序
在 AI 辅助开发的场景下,SDD 与 TDD 并非独立存在,而是形成了一条严密的流水线。
标准执行顺序:
graph LR
A[SDD: 定义规范与验收标准] --> B[TDD-Red: 生成失败的测试用例]
B --> C[Coding-Green: 生成通过测试的代码]
C --> D[Refactor: 重构优化]
D --> E{所有功能完成?}
E -->|否 | A
E -->|是 | F[交付]
为什么必须是这个顺序?
- SDD 定目标:明确“做什么”,为 AI 提供精准的 Prompt 上下文。
- TDD 立标尺:在代码存在之前,先根据规范生成“考卷”(测试)。此时运行测试必然失败(Red),这证明了测试的有效性和独立性。
- Coding 做交付:AI 的目标非常明确——“写出能让这张考卷得满分的代码”。这确保了代码是精准匹配规范的,避免了 AI 自由发挥产生的冗余逻辑或偏差。
关键原则:永远不要先生成业务代码再补测试。先有规范,再有测试(Red),最后才有代码(Green) ,这是保证 AI 生成质量的核心纪律。
3. 实战案例:从零开发前端任务看板系统
项目目标:开发一个类似 Trello 的任务看板前端系统
技术栈:React + TypeScript + Vitest + Testing Library + Zustand
核心功能:任务创建、拖拽排序、状态流转、优先级展示
3.1 阶段一:SDD 规范定义(蓝图绘制)
执行人:资深开发/架构师(人类主导)
目标:产出机器可读的规范文档 specs/task-board.md。
规范文档示例
# 任务看板系统规范 (Task Board Spec)
## 1. 数据结构定义
### Task (任务)
```yaml
id: string (uuid, required)
title: string (max_length: 100, required)
priority: enum ['low', 'medium', 'high']
status: enum ['todo', 'in_progress', 'done']
2. 组件规范:TaskCard
-
输入 (Props) :
task: Task 对象onClick: (id: string) => void
-
视觉规则:
- 当
priority为 'high' 时,卡片必须包含 CSS 类名priority-high(红色边框)。 - 当
priority为 'low' 时,卡片包含priority-low(绿色边框)。
- 当
3. 业务规则:状态流转
- 规则: 当任务从 "Todo" 列拖拽至 "Done" 列时。
- 动作: 自动更新该任务的
status字段为 'done'。
4. 验收标准 (Acceptance Criteria)
- AC-01: 渲染高优先级任务时,DOM 元素包含 class "priority-high"。
- AC-02: 点击任务卡片,触发 onClick 回调并传入正确的 task.id。
- AC-03: 调用 moveTask(taskId, 'done') 后,Store 中该任务 status 变为 'done'。
### 3.2 阶段二:TDD 测试先行(考卷生成)
**执行人**:开发者 + AI
**目标**:根据 SDD 中的【验收标准】,生成测试代码,并确认测试**失败**。
#### 操作步骤
1. **Prompt AI**:
> “请阅读 `specs/task-board.md`。根据其中的【验收标准】,使用 Vitest 和 Testing Library 编写 `TaskCard.test.tsx`。
> **注意**:只生成测试文件,不要生成组件实现。确保测试用例覆盖 AC-01 和 AC-02。”
2. **AI 生成测试代码** (`TaskCard.test.tsx`):
```typescript
import { render, screen, fireEvent } from '@testing-library/react';
import { TaskCard } from './TaskCard'; // 此时该文件可能为空或仅含骨架
import { Task } from './types';
const highPriorityTask: Task = {
id: 'task-1',
title: '紧急修复',
priority: 'high',
status: 'todo'
};
test('AC-01: 高优先级任务应显示 priority-high 类名', () => {
render(<TaskCard task={highPriorityTask} onClick={() => {}} />);
const card = screen.getByText('紧急修复').closest('.task-card');
// 此时期望失败,因为实现尚未完成
expect(card).toHaveClass('priority-high');
});
test('AC-02: 点击任务应触发回调并传入 ID', () => {
const handleClick = vi.fn();
render(<TaskCard task={highPriorityTask} onClick={handleClick} />);
fireEvent.click(screen.getByText('紧急修复'));
expect(handleClick).toHaveBeenCalledWith('task-1');
});
```
3. **运行测试 (Red Phase)**:
```bash
$ npm test
# 输出结果:
# ❌ AC-01: Expected element to have class "priority-high" (Received: "")
# ❌ AC-02: Expected function to be called with "task-1" (Received: 0 calls)
# 2 tests failed.
```
✅ **成功标志**:测试全部失败。这证明测试用例是有效的,且真实反映了当前缺失的功能。
### 3.3 阶段三:Coding 精准实现(答题过关)
**执行人**:开发者 + AI
**目标**:编写代码让上述失败的测试变绿。
#### 操作步骤
1. **Prompt AI**:
> “当前的 `TaskCard.test.tsx` 测试失败了。请参考 `specs/task-board.md` 规范,实现 `TaskCard.tsx` 组件,使所有测试通过。
> **要求**:仅实现满足测试所需的逻辑,保持代码简洁。”
2. **AI 生成实现代码** (`TaskCard.tsx`):
```typescript
import React from 'react';
import { Task } from './types';
interface TaskCardProps {
task: Task;
onClick: (id: string) => void;
}
export const TaskCard: React.FC<TaskCardProps> = ({ task, onClick }) => {
// 根据规范:高优先级添加特定类名
const priorityClass = task.priority === 'high' ? 'priority-high' :
task.priority === 'low' ? 'priority-low' : '';
return (
<div
className={`task-card ${priorityClass}`}
onClick={() => onClick(task.id)}
>
{task.title}
</div>
);
};
```
3. **运行测试 (Green Phase)**:
```bash
$ npm test
# 输出结果:
# ✅ AC-01: Passed
# ✅ AC-02: Passed
# All tests passed! 🟢
```
✅ **成功标志**:测试全部通过。此时代码不仅功能正确,而且严格符合 SDD 规范。
4. **重构 (Refactor)**:
* 检查代码是否有重复逻辑?变量命名是否语义化?
* 利用 AI 进行重构,并再次运行测试确保依然全绿。
### 3.4 阶段四:集成与持续迭代
* **循环推进**:针对下一个验收标准(如 AC-03 状态流转),重复 **SDD(补充细节) → TDD(Red) → Code(Green)** 的过程。
* **CI 自动化**:将规范检查和测试运行集成到 CI 流水线,确保每次提交都符合规范且测试通过。
---
## 4. 实施流程详解:红 - 绿 - 重构的 AI 增强版
在传统 TDD 基础上,AI 的加入让每个环节更加高效,但流程纪律不变。
| 阶段 | 传统 TDD | **AI 增强版 SDD+TDD** | 关键动作 |
| :--- | :--- | :--- | :--- |
| **1. 规划** | 脑海中构思测试 | **SDD 文档化**:将构思写入结构化 Spec | 人类定义规则,AI 辅助完善 Spec |
| **2. 红 (Red)** | 手写失败测试 | **AI 生成测试**:基于 Spec 自动生成测试用例 | 确认测试失败,建立基准线 |
| **3. 绿 (Green)** | 手写最少代码 | **AI 生成实现**:基于 Spec+ 测试生成代码 | 确认测试通过,实现功能 |
| **4. 重构** | 人工重构 | **AI 辅助重构**:提出优化建议并自动应用 | 保持测试通过,提升代码质量 |
**核心心法**:
* **Spec 是源头**:没有 Spec 不写测试。
* **测试是契约**:测试不过不写业务代码。
* **AI 是执行者**:人类负责审查 Spec 和测试结果,AI 负责填充中间的实现细节。
---
## 5. 工具链推荐
为了高效落地 SDD+TDD 范式,建议配置以下工具链:
### 5.1 规范管理 (SDD)
* **Markdown + YAML/JSON**:最通用的规范格式,易于人类阅读和 AI 解析。
* **GitHub Spec Kit / OpenSpec**:专门的规范管理工具,支持版本控制和变更追踪。
* **Cursor / JetBrains AI**:IDE 内置能力,可直接读取 Spec 文件作为 Context。
### 5.2 测试框架 (TDD)
* **Vitest**:极速测试框架,完美支持 TypeScript 和 ESM,适合前端项目。
* **Testing Library (React/Vue)**:倡导“以用户视角测试”,避免测试耦合实现细节。
* **Playwright / Cypress**:用于 E2E 测试,验证整体业务流程是否符合 Spec。
### 5.3 AI 编程助手
* **GitHub Copilot**:强大的代码补全和聊天功能,适合生成测试和实现代码。
* **Cursor**:基于整个代码库上下文的理解,特别适合处理 Spec 到 Code 的转化。
* **Codeium / Tabnine**:优秀的替代方案,支持私有化部署。
---
## 6. 最佳实践与团队落地建议
### 6.1 成功关键因素
1. **规范的粒度控制**:
* **宜**:定义清晰的输入输出、状态流转规则、UI 表现规则。
* **忌**:过度纠结于具体的 CSS 像素值或非核心的内部变量名。
2. **验收标准的可测性**:
* 确保每一条验收标准都能直接转化为一条断言(Assertion)。避免使用“用户体验好”、“加载快”等模糊描述,应改为“首屏加载时间 < 1s”。
3. **严格的顺序纪律**:
* 团队需达成共识:**严禁**跳过测试直接生成代码。即使 AI 能一键生成全套代码,也要坚持“先测后码”的流程,以保证质量可控。
4. **人机协作边界**:
* **人类**:负责定义业务价值、审查 Spec 的合理性、确认测试覆盖率、Code Review。
* **AI**:负责将 Spec 转化为测试代码、将测试转化为实现代码、执行重构。
### 6.2 常见陷阱与应对
* **陷阱:Spec 更新滞后**
* *现象*:代码改了,Spec 没改,导致后续 AI 生成基于旧 Spec 的代码。
* *对策*:将 Spec 文件纳入 Git 版本管理,任何代码变更若涉及逻辑修改,必须先更新 Spec。
* **陷阱:测试过于依赖实现细节**
* *现象*:测试绑定了具体的函数名或内部结构,重构即报错。
* *对策*:坚持使用 Testing Library 等工具,只测试“用户可见的行为”,不测试内部实现。
* **陷阱:盲目信任 AI 生成的测试**
* *现象*:AI 生成的测试逻辑有误,导致“假阳性”通过。
* *对策*:在 Red 阶段,开发者必须人工快速浏览生成的测试逻辑,确认其确实反映了 Spec 意图。
---
## 7. 总结与行动路线图
### 7.1 核心回顾
* **SDD** 解决了“做什么”的问题,为 AI 提供了精准的导航。
* **TDD** 解决了“做对没”的问题,为代码质量提供了即时保障。
* **融合范式** (`SDD → TDD-Red → Code-Green`) 是 AI 时代最高效、最可靠的开发流程。
### 7.2 团队行动路线图
建议团队按以下步骤逐步落地:
* **第 1 周:试点启动**
* 选择一个非核心的新功能模块。
* 尝试编写 SDD 规范文档。
* 实践一次完整的 `Spec -> Test(Red) -> Code(Green)` 循环。
* **第 2-3 周:模板沉淀**
* 总结试点经验,制定团队的《SDD 规范文档模板》。
* 配置统一的 AI Prompt 库(用于生成测试、生成代码)。
* 搭建基础的 CI 流水线,自动运行测试。
* **第 1 个月:全面推广**
* 在新项目中强制推行 SDD+TDD 流程。
* 组织内部分享会,交流最佳实践和踩坑经验。
* **第 3 个月:持续优化**
* 探索 Spec 到 Test 的自动化程度提升。
* 引入可视化回归测试,进一步完善质量保障体系。
---
## 8. 附录:快速参考卡片
### 📝 SDD 规范自查清单
- [ ] 数据结构定义是否清晰(类型、必填项)?
- [ ] 组件 Props/Events 接口是否明确?
- [ ] 业务规则是否覆盖了正常流程和异常场景?
- [ ] 验收标准是否可量化、可直接转化为测试断言?
- [ ] 文档格式是否机器可读(Markdown/YAML)?
### 🔄 TDD 执行口诀
> 规范先行定目标,
> 测试生成红光照。
> 代码实现绿通行,
> 重构优化质量高。
> 顺序切记莫颠倒,
> 人机协同效率高。
### 💡 常用 Prompt 模板
**【生成测试】**
```text
角色:资深测试工程师
任务:根据以下 SDD 规范中的【验收标准】,生成 {语言/框架} 测试用例。
输入:
{粘贴 SDD 规范片段}
要求:
1. 只生成测试代码,不生成实现。
2. 覆盖所有验收标准。
3. 确保测试在当前无实现情况下会失败 (Red)。
【生成实现】
角色:资深开发工程师
任务:编写代码通过以下测试用例,并符合 SDD 规范。
输入:
1. SDD 规范:{粘贴规范}
2. 失败的测试文件:{粘贴测试代码}
要求:
1. 只编写让测试通过所需的最小代码集。
2. 遵循 {语言} 最佳实践。
3. 添加必要的类型定义和注释。
参考资料:
- Microsoft Learn: Specification-Driven Development
- Kent Beck: Test-Driven Development: By Example
- GitHub Copilot Documentation: Best Practices for AI Pair Programming
- Testing Library Official Docs