关于 rails-tdd-slices
帮助 Rails 开发者确定 TDD 应从哪个测试边界开始,优先用最少的无关准备验证关键行为。它按变更类型推荐测试类型与路径,并要求实现前确认测试因功能缺失而失败。
主要功能
- 01按行为选择测试边界
- 02推荐测试类型与路径
- 03先验证失败的门槛
- 04测试设计审查节点
- 05指导编写缺陷复现测试
适用场景
- 01为 API 契约变更选择请求测试
- 02在服务边界测试多步编排
- 03为已报告缺陷选择回归测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ midudev/ autoskills --skill rails-tdd-slices安装后在 Claude Code 中输入/rails-tdd-slices确认已加载。
详细介绍
Rails TDD 切片
当任务最难的部分是判断 TDD 应从哪里开始时,请使用此技能。
核心原则: 从价值最高的边界开始,用最少的不必要设置来验证行为。
快速参考
| 变更类型 | 首个 spec | 路径 | 原因 |
|---|---|---|---|
| API 契约、参数、状态码、JSON 结构 | Request spec | spec/requests/ | 验证真实的 HTTP 契约 |
| 针对内聚记录或值对象的领域规则 | Model spec | spec/models/ | 快速反馈领域行为 |
| 跨多个协作者的多步骤编排 | Service spec | spec/services/ | 聚焦于工作流边界 |
| 入队、运行、重试、丢弃行为 | Job spec | spec/jobs/ | 直接捕捉异步语义 |
| 关键 Turbo/Stimulus 或浏览器可见流程 | System spec | spec/system/ | 仅在浏览器交互确实是风险所在时使用 |
| 引擎路由、生成器、宿主集成 | Engine spec | spec/requests/ 或引擎路径 | 普通应用 spec 会遗漏引擎接线——参见 rails-engine-testing |
| Bug 修复 | 复现 spec | Bug 被观察到的位置 | 验证修复并防止回归 |
| 不确定该选哪一层 | 先从更高层边界入手 | — | 先验证真实行为,再深入细节会更容易 |
硬性门槛
DO NOT choose the first spec based on convenience alone.
DO NOT start with a lower-level unit if the real risk is request, job, engine, or persistence wiring.
ALWAYS run the chosen spec and verify it fails for the right reason before implementation.
流程
- 明确行为: 说明要验证的用户可见结果或不变量。
- 找到边界: 判断最先观察到该行为的位置:HTTP 请求、服务入口、模型规则、作业执行、引擎集成或外部适配器。
- 选择最小的有效切片: 选择能验证该行为、又不会牵扯无关层级的 spec 类型。
- 建议路径: 按照常见的 Rails 约定,写出可能的 spec 路径(例如
spec/requests/...、spec/services/...、spec/jobs/...、spec/models/...)。 - 编写一个失败示例: 保持精简;一个示例就足以打开门槛。
- 运行并验证: 确认失败是因为缺少该行为,而非设置有问题。
- 交接: 继续使用
rspec-best-practices、rspec-service-testing、rails-engine-testing,或适用于该切片的实现技能。
示例
好例子:新增 JSON 端点
# Behavior: POST /orders validates params and returns 201 with JSON payload
# First slice: request spec
# Suggested path: spec/requests/orders/create_spec.rb
RSpec.describe "POST /orders", type: :request do
let(:user) { create(:user) }
let(:valid_params) { { order: { product_id: create(:product).id, quantity: 1 } } }
before { sign_in user }
it "creates an order and returns 201" do
post orders_path, params: valid_params, as: :json
expect(response).to have_http_status(:created)
expect(response.parsed_body["id"]).to be_present
end
end
好例子:新增编排服务
# Behavior: Orders::CreateOrder validates inventory, persists, and enqueues follow-up work
# First slice: service spec
# Suggested path: spec/services/orders/create_order_spec.rb
RSpec.describe Orders::CreateOrder do
subject(:result) { described_class.call(user: user, product: product, quantity: 1) }
let(:user) { create(:user) }
let(:product) { create(:product, stock: 5) }
it "returns a successful result with the new order" do
expect(result).to be_success
expect(result.order).to be_persisted
end
end
测试反馈检查点
编写并运行首个失败的 spec 后,暂停实现,先提交测试以供审查:
CHECKPOINT: Test Design Review
1. Present: Show the failing spec(s) written
2. Ask:
- Does this test cover the right behavior?
- Is the boundary correct (request vs service vs model)?
- Are the most important edge cases represented?
- Is the failure reason correct (feature missing, not setup error)?
3. Confirm: Only proceed to implementation once test design is approved.
为何重要: 基于设计不佳的测试进行实现会浪费 TDD 周期。现在花 2 分钟审查测试,可以避免之后全面重写。
交接: 确认测试设计后 → 使用 rspec-best-practices 完成完整的 TDD 门槛周期。
常见问题
| 问题 | 应对方法 |
|---|---|
| 因为 PORO spec 简单,就从它开始 | 简单 ≠ 高信号——应选择能验证真实行为的边界 |
| 运行任何 spec 之前就编写三种类型的 spec | 选择一个切片,运行它,验证失败后再继续 |
| 所有情况都默认使用 request spec | 有些领域规则在模型层或服务层验证效果更好 |
| 用 model spec 验证控制器行为 | 控制器和 API 需要在 request 层验证 |
| 默认使用 controller spec 作为 HTTP 入口 | 除非代码库中有现成理由,否则优先使用 request spec |
| 过早转向 system spec | 仅在较低层无法验证关键浏览器流程时使用 |
| “之后再补 request spec” | spec 就是门槛——只有首个切片因正确原因失败后,才能开始实现 |
| 首个 spec 需要过多工厂设置 | 设置过多 = 边界选错。简化或调整切片。 |
集成
| 技能 | 何时串联使用 |
|---|---|
| rspec-best-practices | 选择第一个切片后,用于正确执行 TDD 循环 |
| rspec-service-testing | 第一个切片是服务对象规格时 |
| rails-engine-testing | 第一个切片属于引擎时 |
| rails-bug-triage | 起点是现有错误报告时 |
| refactor-safely | 任务主要涉及结构调整,且需要先编写特征测试时 |
评论
支持 Markdown