# Rails Testing

Apply Rails testing standards with Minitest, fixtures, and pragmatic coverage boundaries.

- Repository: https://github.com/marckohlbrugge/37signals-skills (730 stars)
- Category: Testing
- License: see repository
- Last updated: 2026-06-09
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add marckohlbrugge/37signals-skills --skill rails-testing -g -a claude-code -y`
Codex: `npx skills add marckohlbrugge/37signals-skills --skill rails-testing -g -a codex -y`
Cursor: `npx skills add marckohlbrugge/37signals-skills --skill rails-testing -g -a cursor -y`
Gemini CLI: `npx skills add marckohlbrugge/37signals-skills --skill rails-testing -g -a gemini-cli -y`

## Description

Apply Rails testing standards with Minitest, fixtures, and pragmatic coverage boundaries. Use when creating tests, reviewing test quality, or improving flaky and slow Rails test suites.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Rails Testing

Use for test-writing and test-review tasks. Patterns from Campfire and Fizzy test suites.

## Defaults

- Minitest + fixtures. No RSpec, no FactoryBot.
- Test behavior, not implementation details.
- Keep tests deterministic and fast; `parallelize(workers: :number_of_processors)`.
- Tests ship in the same commit/PR as the feature, not before, not later. Security fixes always include a regression test.
- Never add production complexity for testability (no test-induced design damage).

## Coverage Budget (where 37signals actually spends)

- **Heavy:** model tests (domain invariants, concerns) and controller/integration tests (full request cycle, auth, formats).
- **Light:** a few system tests for the critical happy paths (one smoke test can cover signup→use); job tests only for jobs with real logic.
- **None:** view tests, JS/Stimulus unit tests, exhaustive channel tests. UI behavior is covered indirectly by system tests.
- Don't duplicate the same behavior assertion at multiple layers.

## Fixtures

- Express relationships by label, not ID; use ERB for relative timestamps (`created_at: <%= 1.hour.ago %>`) and shared computed values (one bcrypt digest reused).
- Mirror `app/models` structure in `test/models`: `app/models/card/closeable.rb` ↔ `test/models/card/closeable_test.rb`; shared concerns under `test/models/concerns/`.
- UUID PKs break fixture ordering: generate deterministic, label-derived UUIDv7s in fixtures so `.first`/`.last` are stable and runtime records are always newer.
- Build rich-content fixtures with production code (`ActionText::Attachment.from_attachable(user).to_html`), not hand-written markup.

## Good Practices

The rest: https://github.com/marckohlbrugge/37signals-skills/blob/HEAD/skills/rails-testing/SKILL.md
