让AI写一个会议室预约判断函数,往往很快就能得到代码。但代码能识别“09:00到10:00与09:30到10:30冲突”,并不说明它也能正确处理紧邻会议、完全包含、空时间段和非法输入。真正需要交付的是明确规则和可反复运行的检查。
Superpowers项目里的test-driven-development Skill用于约束编码过程:先为一个行为写测试,确认测试按预期失败,再写最小实现,最后在测试保护下整理代码。本文用“同一天会议室时间冲突判断”完成一个小练习,适合希望提高AI编码可验收性的开发者与小工具制作者。
本文核对了官方Skill文件、安装说明和MIT许可证。下方Python练习由本站自行编写并在本地验证红绿过程,没有把手工运行的测试冒充成Claude Code实际会话,也不表示仅安装Skill就能保证代码质量。
一、先理解这个Skill能做什么
它是一套给编码助手使用的工作方法,不是模型、测试框架或自动修复服务。Skill本身不会替你准备Python,也不会为不存在的业务规则给出权威答案。
它的核心检查是:测试是否先出现,失败是否因为缺少目标行为,最小实现是否使测试通过,以及重构后已有测试是否仍通过。只看到最终绿色结果,无法证明测试曾经抓住问题。
适合本篇练习的原因很具体:会议冲突判断输入少、输出明确,能用小测试覆盖重要边界。完整预约系统还涉及时区、并发、权限与持久化,不能靠这个函数就宣布完成。
二、安装与准备:先让工具能发现Skill
如果你已经安装Superpowers,并且当前编码工具能够发现test-driven-development,就不用重复复制同名目录。先在新会话中询问助手是否能找到该Skill,并要求读取实际文件;只复述“TDD很好”不能证明加载成功。
本篇以Claude Code为安装入口。Superpowers官方README目前给出的官方插件市场命令是:
/plugin install superpowers@claude-plugins-official这是在Claude Code支持插件的交互环境中执行的命令,不是PowerShell或普通终端的系统命令。按工具提示完成安装后,新建会话检查插件是否可用;不同版本界面以官方说明为准。
已经通过其他市场安装的用户不要再装第二份。若使用其他编码工具,查看官方README对应工具的安装段落,不能把Claude插件路径直接当成通用Skill路径。
文章下方资源区提供Superpowers源码包,所需文件是其中的skills/test-driven-development/SKILL.md。下载包用于检查和离线留存,不是双击安装程序。解压后先看README与LICENSE,不需要运行包内脚本来完成本篇练习。网盘包版本以资源信息表为准,在线插件市场可能更新更快,二者不能混称同一版本。
接着确认电脑有Python 3:
python --version本文只用标准库unittest,不需要安装第三方依赖。建立一个空练习目录,把之后的booking.py与test_booking.py放在同一层,避免和现有项目混在一起。
三、把业务边界先写清楚
我们约定输入是一天内的整数分钟:09:00写作540,10:00写作600。每个会议用开始和结束两个数表示。
- 每段时间必须满足0≤开始<结束≤1440。
- 只判断同一天,不接受跨午夜会议。
- 采用左闭右开区间:09:00到10:00结束后,10:00到11:00可以紧接着开始,不算冲突。
- 两段部分重叠、完全相同或一段包含另一段,都算冲突。
- 小数、字符串和布尔值都拒绝,非法输入抛出ValueError。
紧邻是否允许,是业务选择,不是算法替你决定的事实。如果客户需要清洁或布置间隔,应先追加明确规则,再写对应测试,而不是悄悄改变现有判断。
四、第一轮:先看到一个有意义的失败
可以给已加载Skill的助手这样的任务说明:
请使用 test-driven-development Skill。
只做同一天整数分钟的会议冲突判断,不做网页和数据库。
先复述边界,再写一个部分重叠的测试并运行。
确认失败原因是缺少目标行为,不是导入或语法错误。
然后写最小实现使测试通过,给出实际命令和退出状态。手动跟做时,先建立booking.py,让函数暂时返回False。它只是用来得到可导入、可运行的练习起点,不是业务实现。
def overlaps(a_start, a_end, b_start, b_end):
return False再建立test_booking.py:
import unittest
from booking import overlaps
class BookingTests(unittest.TestCase):
def test_partial_overlap(self):
self.assertTrue(overlaps(540, 600, 570, 630))
if __name__ == "__main__":
unittest.main()在两个文件所在目录运行:
python -m unittest -v此时应看到断言失败,因为False不满足预期的True。本站实际运行这一阶段得到退出码1。ModuleNotFoundError、拼错函数名和语法错误,都不能作为这个行为已被测试覆盖的证明。先修复环境问题,再确认真正的断言失败。
接着只把返回表达式改成下面一行,再运行同一命令:
return a_start < b_end and b_start < a_end这一轮测试通过,实际退出码为0。先不要宣布函数全部完成,它还没有检查非法输入。
五、第二轮:用边界测试推动实现
先在BookingTests类中追加下面的方法,保留第一轮测试:
def test_touching_is_allowed(self):
self.assertFalse(overlaps(540, 600, 600, 660))
def test_separate(self):
self.assertFalse(overlaps(540, 600, 660, 720))
def test_contained(self):
self.assertTrue(overlaps(540, 720, 600, 660))
def test_identical(self):
self.assertTrue(overlaps(540, 600, 540, 600))
def test_symmetry(self):
self.assertEqual(overlaps(540, 600, 570, 630),
overlaps(570, 630, 540, 600))
def test_invalid_interval(self):
for values in [(600, 600, 700, 800), (700, 600, 800, 900),
(-1, 30, 40, 60), (1380, 1500, 20, 30)]:
with self.subTest(values=values), self.assertRaises(ValueError):
overlaps(*values)
def test_minutes_must_be_integers(self):
for x in [540.5, "540", True]:
with self.subTest(value=x), self.assertRaises(ValueError):
overlaps(x, 600, 570, 630)再次运行测试。部分有效区间会通过,但非法输入检查应失败。一行表达式没有主动抛出约定异常,遇到字符串还会产生不符合约定的TypeError。本站记录的这次运行退出码为1,说明新增测试确实抓住了遗漏。
确认失败原因后,把booking.py改为最终实现:
def overlaps(a_start, a_end, b_start, b_end):
values = (a_start, a_end, b_start, b_end)
if any(type(x) is not int for x in values):
raise ValueError("时间必须是整数分钟")
if not (0 <= a_start < a_end <= 1440):
raise ValueError("第一段时间无效")
if not (0 <= b_start < b_end <= 1440):
raise ValueError("第二段时间无效")
return a_start < b_end and b_start < a_end这里严格检查整数类型,是为了让True不会被当成1分钟。它是本练习明确的输入契约,不能推广成所有Python项目都应禁止布尔值或整数子类。
最后重新运行测试。本站实际执行8个测试方法,全部通过,退出码0。带subTest的方法覆盖多个非法样本,因此不能把“8个方法”误写成“只有8组输入”。
六、整理和交付时要保留哪些东西
通过后可以整理变量名或增加说明,但每次整理都要再跑全部测试。不要为了让测试变绿,把预期True改成False,也不要删除难以通过的边界用例。
本练习交付四项即可:业务边界说明、booking.py、test_booking.py、测试命令与结果记录。若由AI执行,要求它展示实际运行输出,并由你复跑一次。“理论上通过”不能代替运行结果。
集成进预约应用前,还应单独验证多人同时提交、数据库事务和重复请求。两个用户都在保存前查到“没有冲突”,仍可能同时写入重叠预约;这属于并发控制问题,不能用本篇纯函数测试代替。
七、常见问题与排查顺序
- 找不到Skill:先检查当前工具是否安装在正确位置、是否需要新建会话,再检查是否存在同名旧副本。
- 测试文件没有被发现:确认文件名为test_booking.py,运行目录正确,类继承unittest.TestCase,方法以test_开头。
- 一开始测试就全部通过:检查是否已经写了实现、测试是否真的被发现,以及断言是否覆盖目标行为。
- 助手一次性给出全部代码:让它按一个行为分阶段展示,保留失败记录;完整示例可供阅读,但复制最终版不能冒充经历了TDD。
- 想支持跨天预约:先重新定义日期和时区模型。本篇的0到1440范围会拒绝跨天输入,这是设计边界,不是需要绕过的限制。
这个Skill的价值,是把编码过程拆成能检查的小步。业务规则需要人确认,测试仍需审查,但先看见目标测试失败,再让最小实现通过,会让遗漏更早暴露,也让后续修改有明确的验收依据。
八、下一条需求怎样继续做
假设后来增加“同一会议室两场预约之间需要留十分钟”的需求,不要先把所有结束时间加十,再观察网页看起来是否合理。先确认缓冲是否只作用于相邻预约、是否允许当天结束时超过午夜,以及历史预约是否采用同一规则。
在规则明确后,给它写一个独立测试:09:00到10:00与10:05到11:00应视为冲突;10:10开始则允许。先运行并确认当前实现不满足新需求,再决定是扩展函数参数,还是在调用层计算占用时间。这个设计选择应写在变更说明里,不能只修改测试预期。
同时保留原有“不含缓冲时紧邻允许”的测试,防止新需求无意改变旧接口。如果决定更换接口,则明确迁移调用方并更新文档。完成后检查所有测试及实际调用点,而不是仅运行新增的一条测试。
这样一次小改动会留下三种可复查证据:新增业务规则、针对该规则的失败记录、修复后全部检查通过的记录。以后换工具、换模型或由同事接手,都能继续使用这套证据判断修改是否可靠。
官方来源与下载说明
资源表中的下载入口提供现有Superpowers包,包含本篇所用Skill、README与MIT许可证;本篇未制作或标注不存在的新版本。保留源码中的版权与许可说明,第三方工具及模型服务的条款另行适用。

还没有公开评论,欢迎分享你的想法。