From rails-agent-skills
Writes, reviews, and configures RSpec tests in Ruby on Rails following TDD workflow. Executes specs via bundle exec rspec and captures actual test output.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rails-agent-skills:write-testsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill when the task is to write, review, or clean up RSpec tests.
Use this skill when the task is to write, review, or clean up RSpec tests.
| Aspect | Rule |
|---|---|
| Spec types | Model: domain logic / pure domain → start here; Request: HTTP endpoints; Job: background processing; Service/PORO: clean Ruby; System: E2E cross-layer journey (sparingly) |
| Assertions | Test behavior, not implementation |
| Factories | Minimal attributes; traits for options; prefer build/build_stubbed over create |
| Mocking | Stub external boundaries at class level (e.g. allow(Client).to receive); no Active Record mocking |
| Service specs | Required: describe '.call' and subject(:result) (see assets/output_checklist.md) |
let vs let! | Default to let; use let! only when object must exist before action |
| Example names | Present tense; no should; no and (see assets/output_checklist.md) |
HARD GATE: DO NOT write implementation code before a failing test exists.
When driving new behaviour with RSpec, follow this sequence:
e.g. failure examples in the final artifact.For output format and RED/GREEN proof requirements, see assets/tdd_proof_checklist.md.
RSpec.describe Invoices::MarkOverdue do
describe '.call' do
subject(:result) { described_class.call(invoice: invoice) }
context 'when the invoice is overdue and unpaid' do
let(:invoice) { create(:invoice, due_date: 2.days.ago, paid_at: nil) }
it 'marks the invoice overdue' do
expect { result }.to change { invoice.reload.overdue? }.from(false).to(true)
end
end
end
end
Split and in it/specify descriptions every time — no exceptions.
# BAD — two assertions; if the first fails, the second never runs
it 'returns 201 and creates the record' do; end
# GOOD — one observable outcome per example
it 'returns 201' do; end
it 'creates the record' do; end
| Cause | Fix |
|---|---|
| Time-dependent logic | freeze_time / travel_to; never set past dates as shortcut |
| State leakage | Each example sets up own state; avoid before(:all) |
| Async jobs | queue_adapter = :test + have_enqueued_job; never assert side-effects imperatively |
| External HTTP | WebMock / VCR; never allow real network in CI |
| DB state bleed | Transactional fixtures or DatabaseCleaner; never share let! across contexts |
| Race conditions | Explicit Capybara waits; avoid sleep |
| Imprecise assertions | change.from().to() over final state; exact values over be_truthy/be_falsey; see rule 16 |
Load these files only when their specific content is needed:
answer.md showing plan, spec, realistic Observed RED/GREEN outputs, and verification tables.frozen_string_literal, subject(:result), and TDD proof format).2plugins reuse this skill
First indexed Jun 21, 2026
npx claudepluginhub igmarin/rails-agent-skillsWrites, fixes, and refactors RSpec tests for Ruby/Rails apps using describe/it blocks, expect matchers, test doubles, FactoryBot, and TDD best practices. Activates on spec files or test queries.
Assists writing, reviewing, and improving RSpec tests for Ruby on Rails apps including model, controller, system, and integration specs using Better Specs and thoughtbot best practices.
Guides RSpec testing for Ruby and Rails apps covering model specs, request specs, system specs, factories, mocks, and TDD workflow. Triggers on RSpec keywords and testing scenarios.