[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-settings":3,"posts-all":12,"post-sdd-tdd-ai-development":37},{"siteName":4,"siteDescription":5,"authorName":6,"copyright":7,"logoSymbol":8,"createdAt":9,"updatedAt":10,"id":11},"DICE","前端工程师的技术日志，记录 AI 探索与独立开发的思考","dice","Copyright © 2026 Dice. All rights reserved.","https:\u002F\u002Fstatic.diceio.com\u002Ff\u002Fb263d41b758729f8a32abdfeed19f620b85b22e9f4e2a126b2bd016f88a4df41",1782794723207,1783653454363,"6a4349e3ab9e79d68cae07a4",[13,28],{"id":14,"slug":15,"title":16,"summary":17,"content":18,"category":19,"categorySlug":20,"tags":21,"featured":23,"date":24,"readTime":25,"cover":26,"views":27},"6a56013565da7e1d061c1315","ai-coding-developer-ability","AI 时代开发者正在失去什么？从 AI Coding 到工程能力的反思","从 AI 自动生成代码，到 AI 辅助完成完整项目开发，开发效率正在被重新定义。但当我们越来越依赖 AI 时，是否正在减少对源码、架构和设计能力的深入理解？本文记录我在 AI 开发实践中的思考与探索。","","AI","ai",[20,22],"思考",false,"2026-07-14","1 分钟阅读","\u002Fcovers\u002Fpost-1.webp",0,{"id":29,"slug":30,"title":31,"summary":32,"content":18,"category":19,"categorySlug":20,"tags":33,"featured":23,"date":36,"readTime":25,"cover":26,"views":27},"6a53e5e465da7e1d061c04e6","sdd-tdd-ai-development","为什么 AI 时代反而需要 SDD 和 TDD？","AI Coding 时代，SDD帮助我们明确“开发什么”，TDD帮助我们验证“是否正确”。本文结合 OpenSpec、真实项目案例和个人理解，探索两者如何结合，构建更高效、更可靠的软件开发流程。",[20,34,35],"SDD","TDD","2026-07-12",{"id":29,"slug":30,"title":31,"summary":32,"content":38,"category":19,"categorySlug":20,"tags":39,"featured":23,"date":36,"readTime":40,"cover":26,"views":27},"\n最近在学习 AI Coding 相关的开发流程时，我接触到了两个之前没有深入理解的概念：\n\n- SDD（Specification Driven Development，规范驱动开发）\n- TDD（Test Driven Development，测试驱动开发）\n\n最开始接触 SDD 的时候，我其实比较容易理解。\n\n因为它和传统的软件开发流程非常接近：\n\n```text\n需求分析\n↓\n产品设计\n↓\nUI设计\n↓\n技术方案\n↓\n前端\u002F后端开发\n↓\n测试\n↓\n上线\n````\n\n但是 TDD 一开始让我非常困惑。\n\n为什么测试要提前写？\n\n测试不是应该在代码完成之后，用来验证代码有没有问题吗？\n\n而且如果测试用例先写，那开发之前怎么可能考虑完整所有情况？\n\n带着这些疑问，我开始深入了解 TDD 和 SDD，并结合 AI Coding 时代的软件开发方式重新思考这两个概念。\n\n这篇文章记录一下我的理解过程。\n\n# 一、为什么现在重新关注 SDD 和 TDD？\n\n在传统软件开发过程中，通常是：\n\n```text\n需求\n↓\n开发人员理解需求\n↓\n设计方案\n↓\n编写代码\n↓\n测试\n↓\n上线\n```\n\n这种方式在过去几十年中非常成熟。\n\n但是随着软件复杂度提升，以及 AI Coding 工具出现，我发现一个新的问题：\n\n&gt; 现在写代码越来越容易，但是确定“应该写什么代码”越来越困难。\n\n以前：开发人员需要花大量时间写代码。\n\n现在：AI 可以快速生成大量代码。例如：\n\n告诉 AI：\n\n```text\n帮我开发一个博客系统\n```\n\nAI 很快可以生成：\n\n* 页面\n* API\n* 数据库模型\n* 组件代码\n\n但是 AI 不知道：\n\n* 这是个人博客还是商业博客？\n* 是否需要用户体系？\n* 是否需要权限？\n* 是否需要评论？\n* 技术架构是什么？\n* 哪些功能是必须的？\n\n最终可能生成一个：\n\n&gt; 看起来完整，但是并不是我真正想要的系统。\n\n所以 AI Coding 时代，最大的挑战逐渐从：“如何写代码” 变成：“如何准确描述我要构建什么”。\n\n这也是 SDD 重新受到关注的重要原因。\n\n\n# 二、我对 SDD 的理解\n\nSDD 可以理解为：\n\n&gt; 在真正开始开发之前，通过 Specification（规范）明确系统应该是什么样子。\n\n它解决的问题是：\n\n&gt; 我们到底要开发什么？\n\n传统开发：\n\n```text\n需求文档\n↓\n开发\n```\n\n而 SDD：\n\n```text\n需求\n↓\nSpecification\n↓\n设计\n↓\n任务拆分\n↓\n开发\n```\n\n# 三、通过一个真实项目理解 SDD\n\n假设我要开发一个： ```打牌记账微信小程序```\n\n需求：\n\n&gt; 用户创建牌局房间，邀请朋友加入，然后记录每个人输赢，最终自动结算。\n\n如果直接开发：可能马上开始：\n\n```text\n创建房间页面\n↓\n房间接口\n↓\n数据库\n↓\n结算逻辑\n```\n\n但是开发过程中会不断遇到问题：\n\n* 房间有没有人数限制？\n* 房主退出怎么办？\n* 输赢如何计算？\n* 是否支持重新结算？\n* 是否保存历史记录？\n\n这些问题如果没有提前明确，开发过程会不断返工。\n\n## 使用 SDD 后\n\n首先拆 Specification。例如：\n\n## requirements.md\n\n描述业务规则：\n\n```md\n功能：\n创建牌局房间\n\n用户输入：\n- 房间名称\n\n系统返回：\n- 房间ID\n\n规则：\n- 创建者拥有管理权限\n- 一个房间最多10人\n- 房间创建后可以邀请成员加入\n```\n\n---\n\n## design.md\n\n描述技术设计：\n\n系统架构：\n```text\n微信小程序\n↓\nNestJS API\n↓\nMySQL\n```\n\n数据模型：\n\n```text\nRoom\nid\nname\ncreatorId\nstatus\ncreatedAt\n```\n\n接口：\n\n```text\nPOST \u002Frooms\n```\n\n---\n## tasks.md\n\n拆分开发任务：\n\n```text\nTask1:\n创建Room数据库表\n\nTask2:\n实现createRoom Service\n\nTask3:\n实现创建房间接口\n\nTask4:\n增加权限校验\n```\n\n这样开发人员或者 AI Agent 才知道：\n\n* 为什么做\n* 做什么\n* 怎么拆分\n\n所以：\n\n&gt; SDD解决的是“开发方向问题”。\n\n\n# 四、为什么 AI Coding 时代更加需要 SDD？\n\n以前：\n\n```text\n需求\n↓\n人理解需求\n↓\n人写代码\n```\n\n现在：\n\n```text\n需求\n↓\nSpecification\n↓\nAI Agent\n↓\n生成代码\n```\n\nAI 最大的问题不是不会写代码。\n\n而是不知道：\n\n&gt; 你真正想要什么。\n\nSpecification 就成为：\n\n人与 AI 之间的沟通层。\n\n它把人的想法转换成 AI 可以执行的约束。\n\n\n# 五、我最开始不理解 TDD 的地方\n\n相比 SDD，TDD 一开始让我更加疑惑。\n\n传统开发：\n\n```text\n写代码\n↓\n运行\n↓\n发现问题\n↓\n修改\n```\n\n而 TDD：\n\n```text\n写测试\n↓\n测试失败\n↓\n写代码\n↓\n测试通过\n↓\n重构\n```\n\n我的第一个疑问：\n\n&gt; 为什么要反过来？\n\n后来我理解：TDD 并不是：\n\n“提前写很多测试代码”。\n\n它真正表达的是：\n\n&gt; 先定义代码应该具备什么行为，再实现这个行为。\n\n\n\n# 六、通过一个真实案例理解 TDD\n\n还是以：```创建房间功能```为例。\n\nSDD 已经拆出来：\n\n```text\nTask:\n实现 createRoom Service\n```\n\n### 普通开发方式\n\n开发人员可能直接：\n\n```typescript\nasync createRoom(dto){\n\n return repository.save(dto)\n\n}\n```\n\n然后测试发现问题：\n\n* 房间名称为空也可以创建\n* 返回格式不符合要求\n* 缺少权限判断\n\n于是：\n\n```text\n写代码\n↓\n发现问题\n↓\n修改代码\n```\n\n### TDD 的实际过程：红 → 绿 → 重构\n\nTDD 通常遵循：\n\n```text\nRed\n↓\nGreen\n↓\nRefactor\n```\n\n#### 第一步：Red\n\n先写测试。例如：\n\n```typescript\ntest(\n\"创建房间应该成功\",\nasync()=&gt;{\n\nconst room =\nawait service.createRoom({\n name:\"周末麻将\"\n})\n\n\nexpect(room.name)\n.toBe(\"周末麻将\")\n\n})\n```\n\n运行：\n\n```text\nFAIL\n```\n\n失败是正常的。因为功能还没有实现。\n\n#### 第二步：Green\n\n实现最简单代码：\n\n```typescript\nasync createRoom(dto){\n\nreturn {\n      name:dto.name\n}}\n```\n\n再次运行：\n\n```text\nPASS\n```\n\n#### 第三步：Refactor\n\n现在代码可以优化。\n\n例如：拆分：\n\n```text\nRoomService\n↓\nRoomValidator\n↓\nRoomRepository\n```\n\n只要测试通过：就可以放心重构。\n\n# 八、TDD最大的价值：让重构变得安全\n\n这是我后来认为 TDD 最重要的价值。\n\n很多人认为：\n\n&gt; TDD只是为了减少 Bug。\n\n但是实际上：\n\n&gt; TDD 最大的价值，是让未来修改代码变得更加安全。\n\n例如：\n\n第一版：\n\n```typescript\nfunction calculateScore(){\n\n}\n```\n\n半年后：业务越来越复杂：\n\n* 不同牌局规则\n* VIP积分\n* 活动奖励\n* 特殊计算方式\n\n代码可能变成：\n\n```typescript\ncalculateScore(){\n\nif(){\n}\n\nif(){\n}\n\nif(){\n}\n\n}\n```\n\n这时候开发人员想重构。拆成：\n\n```text\nScoreCalculator\n\nRuleEngine\n\nBonusCalculator\n```\n\n如果没有测试：只能依靠人工验证。风险很高。\n但是有 TDD：\n\n```text\n修改代码\n↓\n运行测试\n↓\n测试通过\n↓\n确认行为没有改变\n↓\n安全上线\n```\n\n所以：\n\n&gt; 测试不是限制重构，而是保护重构。\n\n# 九、TDD 的测试能覆盖全部情况吗？\n\n这是我最开始最大的疑问。如果测试不能考虑全面：\n\n&gt; 那 TDD 有意义吗？\n\n后来理解：\n\n&gt; TDD 不要求一次性预测未来所有情况。\n\n真实项目中：\n\n测试会随着需求变化不断增加。\n\n例如：\n\n第一版本：\n\n```text\n创建房间\n\n记录输赢\n\n结算\n```\n\n测试：\n\n```text\n创建房间成功\n\n金额计算正确\n```\n\n上线之后：\n\n用户提出：\n\n&gt; 玩家中途退出怎么办？\n\n那么增加：\n\n```text\n玩家退出重新计算\n```\n\n对应增加测试。所以测试不是：\n预测未来。\n\n而是：\n\n记录当前系统应该具备的行为。\n\n\n# 十、为什么 TDD 会导致更好的架构设计？\n\n这是 TDD 最容易被忽略的价值。原因：\n\n&gt; 难测试的代码，通常也是难维护的代码。\n\n例如：\n\n一个订单服务：\n\n```typescript\nclass OrderService{\n\ncreateOrder(){\n\n    查询用户\n    查询商品\n    检查库存\n    计算价格\n    创建订单\n    扣库存\n    发送邮件\n}}\n```\n\n测试这个方法，需要准备：\n\n* 数据库\n* 用户数据\n* 商品数据\n* 库存服务\n* 邮件服务\n\n测试非常困难。\n\n这说明：代码职责太多，耦合严重。\n\n于是拆分：\n\n```text\nOrderService\n↓\nInventoryService\nPricingService\nNotificationService\n```\n\n每个模块：\n\n* 职责单一\n* 可以独立测试\n* 更容易维护\n\n所以 TDD 会推动：\n\n* 单一职责原则\n* 低耦合设计\n* 面向接口设计\n* 模块化架构\n\n\n# 十一、SDD 和 TDD 如何结合？\n\n如果使用 OpenSpec：生成：\n\n```text\nproposal\ndesign\ntasks\n```\n\n是不是直接 apply 执行？我的理解：不是简单执行。\n\n更合理流程：\n\n```text\n需求\n↓\nOpenSpec\n↓\nproposal\n↓\ndesign\n↓\ntasks\n↓\n选择Task\n↓\n编写测试\n↓\n实现代码\n↓\n运行测试\n↓\n重构\n↓\nTask完成\n```\n\n# 十二、OpenSpec 怎么知道执行哪些测试？\n\n这里容易产生误解。\n\n&gt; OpenSpec 本身不知道。\n\n因为：\n\n&gt; SDD 和 TDD 解决的问题不同。\n\nSDD：\n\n```text\n我要做什么\n```\n\nTDD：\n\n```text\n如何证明做对了\n```\n\n两者通过工程规范连接。\n\n例如：\n\n团队规定：每个 Task, 必须包含：\n\n```text\nImplementation\n\nTest\n\nValidation\n```\n\n例如：\n\n```text\nTask:\n实现createRoom API\n\nImplementation:\n创建接口\n\nTest:\n创建成功\n空名称失败\n\nValidation:\nnpm test\n```\n\n# 十三、TDD实际使用哪些工具？\n\nTDD不是一个工具。而是一种开发方法。常见测试工具：\n\n\n* Jest\n* Vitest\n* React Testing Library\n\n\n\n\n# 十四、AI Agent 为什么更加需要 TDD？\n\nAI 写代码最大的风险：不是不会写。而是：\n\n* 理解错误\n* 修改错误文件\n* 过度实现\n* 破坏已有逻辑\n\nTDD提供一个反馈闭环：\n\n```text\nAI生成代码\n↓\n运行测试\n↓\n测试失败\n↓\nAI根据错误修复\n↓\n测试通过\n```\n\n测试成为：AI Agent 的自动反馈机制。\n\n\n# 十五、我现在对 SDD 和 TDD 的最终理解\n\n如果把开发软件比作建房子：\n\n#### SDD\n\n类似：建筑设计图。决定：\n\n```text\n我要建什么房子？\n\n房间如何布局？\n```\n\n#### TDD\n\n类似：施工验收标准。保证：\n\n```text\n每个结构符合要求。\n```\n\n所以：\n\nSDD解决：\n\n&gt; 我们是不是在开发正确的东西？\n\nTDD解决：\n\n&gt; 我们开发出来的东西是不是正确？\n\n# 十六、总结\n\n以前的软件开发：\n\n```text\n人理解需求\n↓\n人设计方案\n↓\n人写代码\n↓\n人测试\n```\n\nAI Coding 时代：\n\n```text\n人定义 Specification\n↓\nAI生成任务\n↓\nAI编写代码\n↓\nTDD验证\n```\n\n人的角色正在从：\n\n&gt; 代码生产者\n\n转变为：\n\n&gt; 系统设计者和约束制定者。\n\n最终我的理解：\n\n&gt; SDD 是 AI 时代解决“方向问题”的方法。\n\n&gt; TDD 是 AI 时代解决“质量问题”的方法。\n\n两者结合，会成为未来 AI 软件开发的重要工作流。\n\n(以上内容是我总结出来的并不代表正确，仅供参考，如有问题可联系我纠正)",[20,34,35],"4 分钟阅读"]