mcpField
W
write-tests

write-tests

github.com/igmarinTesting & quality2843 installsUpdated 5w ago
Repository

About write-tests

A skill for writing, reviewing, and refining RSpec tests. It guides developers through a test-first workflow with behavior-focused examples, deterministic assertions, and concrete RED/GREEN verification.

Key features

  1. 01Test-first RSpec workflow
  2. 02Spec type selection guidance
  3. 03Behavior-focused assertions
  4. 04Flaky test prevention guidance
  5. 05RED/GREEN output requirements

Use cases

  1. 01Testing new application behavior
  2. 02Reviewing or cleaning up RSpec tests
  3. 03Writing service object specs
  4. 04Diagnosing flaky test patterns

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/igmarin/rails-agent-skills --skill write-tests

After installing, type/write-testsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

assets/
complete_example.md
examples.md
output_checklist.md
spec_templates.md
tdd_proof_checklist.md

Details

From the project README

Write Tests

Use this skill when the task is to write, review, or clean up RSpec tests.

Quick Reference

AspectRule
Spec typesModel: domain logic / pure domain → start here; Request: HTTP endpoints; Job: background processing; Service/PORO: clean Ruby; System: E2E cross-layer journey (sparingly)
AssertionsTest behavior, not implementation
FactoriesMinimal attributes; traits for options; prefer build/build_stubbed over create
MockingStub external boundaries at class level (e.g. allow(Client).to receive); no Active Record mocking
Service specsRequired: 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 namesPresent tense; no should; no and (see assets/output_checklist.md)

HARD-GATE

DO NOT write implementation code before a failing test exists.
Run bundle exec rspec and keep the real failure class and message.

Core Process

When driving new behaviour with RSpec, follow this sequence:

  1. Write the failing spec — pick the smallest spec type that exercises the intended behaviour (model > service > request > system), as shown in the Spec types row above.
  2. Run it and confirm the failure message — show the concrete RED failure class/message. Do not leave this as a placeholder template; do not use illustrative e.g. failure examples in the final artifact.
  3. Implement the minimum code to make the spec pass.
  4. Refactor — clean up duplication and naming while keeping the suite green.
  5. Verify — run the full relevant spec file, then the suite, before committing.

For output format and RED/GREEN proof requirements, see assets/tdd_proof_checklist.md.

Service Spec (anchor pattern)
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
One Behavior Per Example

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

Flaky Tests & Deterministic Assertions

CauseFix
Time-dependent logicfreeze_time / travel_to; never set past dates as shortcut
State leakageEach example sets up own state; avoid before(:all)
Async jobsqueue_adapter = :test + have_enqueued_job; never assert side-effects imperatively
External HTTPWebMock / VCR; never allow real network in CI
DB state bleedTransactional fixtures or DatabaseCleaner; never share let! across contexts
Race conditionsExplicit Capybara waits; avoid sleep
Imprecise assertionschange.from().to() over final state; exact values over be_truthy/be_falsey; see rule 16

Extended Resources (Progressive Disclosure)

Load these files only when their specific content is needed:

  • assets/complete_example.md — A complete, step-by-step example of a high-scoring answer.md showing plan, spec, realistic Observed RED/GREEN outputs, and verification tables.
  • assets/examples.md — For code examples of service specs, shared examples, and factory design.
  • assets/spec_templates.md — Standard templates for different types of specs.
  • assets/tdd_proof_checklist.md — Use when the task involves new behavior; defines RED/GREEN proof format, output formatting rules, and GREEN progress bar requirements.
  • assets/output_checklist.md — Complete 18-point checklist for RSpec output structure, conventions, and self-auditing; also defines all output style rules (spec structure, file path mirroring, frozen_string_literal, subject(:result), and TDD proof format).

Output Style

Follow assets/tdd_proof_checklist.md and assets/output_checklist.md. Show real RED/GREEN command output. One behavior per example.

Integration

SkillWhen to chain
plan-testsFirst-slice choice is not obvious
test-serviceThe slice is a service .call
tddFull feature loop through PR

Comments

Markdown supported