addy osmani agent skills 的 test-driven-development 按红灯、绿灯、重构推进。先让新增断言因预期的行为差异而失败,再做最小改动让它通过,最后整理代码并重跑。
准备能独立运行的标签测试
在你当前的练习目录下新建两个文件:tag.mjs 和 tag.test.mjs。先定好标签处理的规则:如果输入是字符串,就去掉首尾空格再转成全小写;如果不是字符串类型,直接返回空字符串。最开始先写最简单的实现,直接把入参原样返回,先靠这个复现预期的行为差异。
export function normalizeTag(value) {
return value;
}
把下面的测试代码存到 tag.test.mjs 里,两个断言分别覆盖字符串、非字符串两种场景,全程不需要额外装第三方测试框架。
import test from 'node:test';
import assert from 'node:assert/strict';
import { normalizeTag } from './tag.mjs';
test('trims and lowercases a tag', () => {
assert.equal(normalizeTag(' JavaScript '), 'javascript');
});
test('returns an empty string for non-string values', () => {
assert.equal(normalizeTag(null), '');
});
红灯阶段要确认失败原因
两个文件都写完之后,在当前目录下运行测试命令。正常情况下的预期报错,是断言拿到了没经过处理的原字符串或者 null 值。如果提示找不到模块,先检查文件名和代码里的导入路径是不是写对了。
node --test tag.test.mjs
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

让 AI 代理更主动、具预见性。用户希望代理主动帮助、提前发现问题或汇报进展时触发。关键词:主动、积极、预见、提醒、proactive、anticipate、take initiative。
让断言通过,再决定是否重构
只需要修改 tag.mjs 里的实现就行:先判断入参类型,确认是字符串之后,再调用 trim() 和 toLowerCase() 做处理。改完之后重新跑刚才的测试命令,确认两个断言全部通过。
export function normalizeTag(value) {
return typeof value === 'string' ? value.trim().toLowerCase() : '';
}

让助手保留红绿两轮证据
请使用 test-driven-development,先运行新增用例并说明为什么失败,再做最小实现并重跑。不要改弱断言。
现在这段实现已经足够精简,可以直接保留。如果团队有规范,想要把类型判断改成提前返回的写法,重构完之后再跑一遍同样的测试命令,保证两种输入场景的输出结果和之前完全一致。










