当前位置: 首页
AI教程
OpenSpec+TDD实践:AI写代码的测试兜底方案

OpenSpec+TDD实践:AI写代码的测试兜底方案

热心网友 时间:2026-06-06
转载

AI 写代码确实效率惊人,但你有没有问过它一个关键问题:“你写的代码真的正确吗?”它会自信地回答“全部通过”,可一运行,全是错误。这种表面上的完美,往往隐藏着最致命的隐患。下面这套方案,用 OpenSpec 来梳理和管理需求定义,用 TDD(测试驱动开发)来保证代码的正确性,两者在实际开发中串联使用,效果非常理想。

OpenSpec + TDD:让 AI 写代码,用测试兜底

为什么必须这样组合

如今越来越多开发者在大量使用 AI 辅助编码,效率确实呈爆发式提升。但运行一段时间后,会察觉到一个令人不安的现象:AI 生成的代码看起来总是滴水不漏。

它不会主动报错,也不会说“这里我不确定”,写出的代码结构清晰、命名规范、注释齐全——简直就是模范代码。可一旦实际运行呢?边界情况被遗漏了,业务逻辑理解出现了偏差,有时甚至会编造一个根本不存在的 API,还自信满满地去调用。你问它“问题解决了吗”,它回答“全部检测通过已经完成”,其实连编译都通不过。

这种现象被称为 AI 的“自洽幻觉”:它总能给出一个看似“合理”的答案,但合理从来不代表正确。

因此核心问题变成了:在代码生成成本越来越低的今天,正确性才是真正稀缺的资源。谁来保障正确性?测试。注意,不是写完代码后补的那种测试,而是 TDD 那种——先写测试,再让 AI 去实现。

但仅有 TDD 还不够。测试能告诉你“代码能不能跑对”,却无法告诉你“需求本身拆分得是否合理”。如果需求拆分歪了,即使所有测试都绿,也是白费功夫。

这就是 OpenSpec 的定位:它负责“做什么”,TDD 负责“做对没”。

整体流程概览

两者的衔接点落在 Apply 阶段。前期用 OpenSpec 把意图理清楚、把方案定下来,到了动手环节,每个 task 内部走 TDD 循环。

Explore → Propose → Apply (TDD循环) → Archive
│          │           │                │
│思考讨论  │proposal.md│ Red→Green→Refactor│归档 + sync specs
│明确意图  │design.md  │ 逐task推进      │
│          │tasks.md   │                │
│          │specs/     │                │

四个阶段各司其职,但并不是僵化的瀑布流——你随时可以从 Apply 退回 Propose 去修改设计,也可以跳过 Explore 直接开始。关键在于每个阶段解决不同的问题。

Tasks 的正确写法

这是整个方案中最关键的一环。常见的 task 写法是“实现用户登录功能”——这种粒度对 AI 来说过于粗糙,它会一口气把登录、注册、token 生成全部写完,测试?根本不存在。

正确做法是将测试 task 和实现 task 成对出现:

## Tasks
- [ ] 为用户登录写失败路径测试(无效密码、不存在用户)
- [ ] 实现登录逻辑使测试通过
- [ ] 为token生成写测试(过期、签名验证)
- [ ] 实现token生成使测试通过
- [ ] 重构:提取认证中间件
- [ ] 为中间件写集成测试
- [ ] 实现中间件使测试通过

先测试、再实现、中间穿插 refactor。这并非形式主义——这个顺序决定了 AI 在 Apply 阶段的行为模式。如果你不显式写出测试 task,AI 会直接跳到实现,然后补上一堆 happy path 测试来交差。

Apply 阶段的 TDD 节奏

每个 task 内部遵循经典的 Red-Green-Refactor 循环:

单个 Task 的执行流程:

1. Red → 写测试,运行,确认失败
2. Green → 写最少代码让测试通过
3. Refactor → 清理代码,测试仍通过
4. ✓ 标记task完成

有一个细节特别容易被忽略:第 1 步的“确认失败”非常关键。假如你一上来测试就绿了,那说明两种情况——要么这个功能已经实现了(那这个 task 就是多余的),要么你的测试写得有问题(没测到关键点上)。无论哪种情况,都必须停下来仔细分析。

“写最少代码”也有讲究。AI 特别喜欢过度实现——你让它通过一个测试,它顺手把后面三个 task 的功能也写了。此时需要在 prompt 里明确约束:只让当前这一个测试变绿,不要多做。

实际操作完整演示

拿“给系统加用户认证”这个需求举例:

# 1. Explore - 理清要做什么
/opsx:explore add-user-auth

# 讨论:用JWT还是session?是否需要第三方登录?密码策略如何制定?

# 2. Propose - 生成方案(task按TDD节奏拆分)
/opsx:propose add-user-auth

# 产出 proposal.md / design.md / tasks.md / specs

# 3. Apply - 逐个task实施
/opsx:apply add-user-auth

Apply 过程中,AI 的实际行为演示:

// Task: "为用户登录写失败路径测试"
// AI写出:
@Test
fun `login with invalid password returns error`() = runTest {
    val testUser = userRepository.createUser("test@example.com", "correct_password")
    val result = loginUseCase.execute("test@example.com", "wrong_password")
    assertThat(result).isInstanceOf(LoginResult.Failure::class.ja va)
    assertThat((result as LoginResult.Failure).reason).isEqualTo("invalid_credentials")
}

@Test
fun `login with nonexistent user returns error`() = runTest {
    val result = loginUseCase.execute("nobody@example.com", "any_password")
    assertThat(result).isInstanceOf(LoginResult.Failure::class.ja va)
}

// → 运行测试 → RED ✗(因为LoginUseCase尚未实现)
// → 标记为已完成 [x]

// Task: "实现登录逻辑使测试通过"
// AI写出:
class LoginUseCase @Inject constructor(
    private val userRepository: UserRepository,
    private val tokenManager: TokenManager
) {
    suspend fun execute(email: String, password: String): LoginResult {
        val user = userRepository.findByEmail(email) ?: return LoginResult.Failure("invalid_credentials")
        if (!user.verifyPassword(password)) {
            return LoginResult.Failure("invalid_credentials")
        }
        val token = tokenManager.createAccessToken(user.id)
        return LoginResult.Success(token)
    }
}

// → 运行测试 → GREEN ✓
// → 标记为已完成 [x]

# 4. 所有task完成后归档
/opsx:archive add-user-auth

Spec 与 Test 的关系

这两者的关系容易混淆,用一个类比说清楚:Spec 是合同,Test 是验收。

合同写的是“用户连续5次登录失败应锁定账户”,这是业务语言,给人看的。验收做的是 account locks after 5 failures 这个测试用例,这是代码语言,给机器跑的。

openspec/specs/auth/spec.md ← 合同(业务语言)
“用户连续5次登录失败应锁定账户”

app/src/test/ja va/.../auth/LoginUseCaseTest.kt ← 验收(代码语言)
fun `account locks after 5 consecutive failures`()

每一条 spec 都应该能映射到至少一个测试——如果有一条 spec 找不到对应的测试,要么是测试遗漏了,要么是这条 spec 写得过于空泛(比如“系统应该安全”这种就无法直接测试)。

反过来也成立:如果你写了一个测试却找不到对应的 spec,说明你在测试一个没有被明确定义过的行为。这种测试不是不能存在,但需要思考它是否应该先变成一条 spec。

推荐 config.yaml 配置

schema: spec-driven

context: |
  开发模式:OpenSpec + TDD
  测试框架:JUnit5 + Truth + Mockk
  # Android项目常用组合
  测试目录:app/src/test/ 和 app/src/androidTest/
  每个task必须先有测试覆盖再写实现

rules:
  tasks:
    - 测试类task和实现类task必须成对出现
    - 每个实现task之前必须有对应的测试task
    - Refactor task的前提是所有测试通过
  design:
    - 设计中需包含testability考虑
    - 标注哪些边界需要mock/stub

这个配置的作用是约束 AI 在 Propose 阶段生成 tasks 时严格遵循 TDD 节奏。如果没有这些 rules,AI 很容易生成“实现 XX 功能”这样笼统的 task,导致测试被完全忽略。

这套方案实际使用下来,最直观的体会不是代码质量大幅提升,而是终于可以在 AI 写完代码之后安心去喝杯咖啡了。测试守住了底线,spec 锁住了意图,即使 AI 出现幻觉,也逃不开这个圈。

来源:https://juejin.cn/post/7623442090362585122
上一篇: 2027人类最终抉择

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
阿里云OpenClaw官方镜像六大场景3分钟开箱即用指南

阿里云OpenClaw官方镜像六大场景3分钟开箱即用指南

先聊聊OpenClaw到底是什么,以及它为什么值得关注。作为阿里云推出的智能助理平台,OpenClaw基于通义千问大模型深度定制,目标很明确:为开发者、创作者、运营者提供一站式的AI赋能解决方案。下面直接切入正题,看看它的六大核心场景。 OpenClaw 智能助理:六大核心场景赋能开发者高效成长 O

时间:2026-06-06 18:43
Moltbot Clawdbot与飞书机器人接入实践

Moltbot Clawdbot与飞书机器人接入实践

简单认识一下 Clawdbot 最近 AI 圈被一款名为 Clawdbot 的产品刷屏了。不管是在国内技术社区,还是刷 TG、X 的时候,几乎都能看到有人在讨论它。 看了一下官方文档,Clawdbot 本质上就是一个偏“个人智能助手”的东西。不过它并不是单独开一个网页给我们用,而是可以直接接入我们平

时间:2026-06-06 18:40
SpringAI与ONNX打造免费离线向量引擎

SpringAI与ONNX打造免费离线向量引擎

前段时间尝试了一个很有意思的项目——原本只是想在 Spring AI 项目中顺手集成 ONNX 模型,结果一上手就停不下来,直接调试到凌晨两点,边调边感慨:整个过程也太丝滑流畅了。 今天就来深入聊聊这件事:如何在 Spring AI 中使用 ONNX 向量模型,实现本地化的文本嵌入能力。 如果你之前

时间:2026-06-06 18:40
AI智能体技能完全指南:让你的AI助手拥有超能力

AI智能体技能完全指南:让你的AI助手拥有超能力

引言:AI Agent 的能力边界在哪里?你的AI编程助手可以编写代码,但它是否真正理解你公司的独特工作流程?能否自动处理你的CI CD流水线?又是否熟悉你日常使用的那些特定工具与API接口?AI Agent Skills正是为解决这一痛点而诞生的——它们作为可复用的能力模块,能够将通用型AI助手转

时间:2026-06-06 18:39
AI编程神器狂揽34k星与Claude Code和Codex绝配

AI编程神器狂揽34k星与Claude Code和Codex绝配

CC Switch:一站式AI编程工具管理神器 今天要介绍的这款实用小工具,名字叫作CC Switch。它是一款跨平台的桌面“All-in-One”助手,专门用于管理主流的AI编程开发工具。目前该项目在GitHub上已经获得了34k+ star,关注度非常高。它的核心卖点很直接:提供一个可视化操作界

时间:2026-06-06 18:39
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜