RS

rspec-unit-testing-standards

Defines mandatory and recommended rules for RSpec structure, naming, and stubbing patterns.

Install

mkdir -p .claude/skills/rspec-unit-testing-standards && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10446" && unzip -o skill.zip -d .claude/skills/rspec-unit-testing-standards && rm skill.zip

Installs to .claude/skills/rspec-unit-testing-standards

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Defines RSpec unit testing rules for this project covering structure, naming, setup patterns, stubbing, doubles, coverage, and test reliability. Use when writing, reviewing, or auditing RSpec specs under spec/unit/.
215 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Validate RSpec unit tests
  • Audit test suite quality
  • Enforce RSpec structure rules
  • Check branch coverage
  • Verify test determinism

How it works

The skill enforces RSpec standards by checking spec file structure, naming conventions, and setup patterns against defined MUST/SHOULD rules.

Inputs & outputs

You give it
spec/unit/path/to_spec.rb
You get back
Compliance report and coverage status

When to use rspec-unit-testing-standards

  • Reviewing RSpec test code
  • Setting up new unit tests
  • Auditing test suite quality

About this skill

RSpec Unit Testing Standards

These rules govern the structure, organization, and quality of all RSpec unit tests in this project. Apply them when writing new tests, reviewing existing ones, or auditing test quality.

Priority Levels

Use RFC-style priority words to reduce ambiguity for AI behavior:

  • MUST: mandatory; do not violate without a documented exception
  • SHOULD: preferred default; may be overridden when a clearer test requires it

Contents

How to use this skill

These rules apply to all RSpec unit specs under spec/unit/. Extend this baseline with domain-specific rules from related skills as needed.

Adoption and enforcement notes:

  • Apply these rules as hard requirements for new and modified unit specs.
  • Legacy specs may violate some rules; treat those as incremental cleanup work.
  • Branch and line coverage are both reported by SimpleCov in this repository.
  • minimum_coverage: { line: 100, branch: 100 } is configured and enforced: a full rake spec:unit run fails when either threshold is missed, and CI fails the pull request with it. Rule 21 is a build gate, not just a review check. See the Test coverage policy in CONTRIBUTING.md for the full policy.
  • Focused runs (SPEC=<glob> rake spec:unit, or rspec <file>) report coverage but do not fail on it, since they load all of lib/ while exercising only a slice.

Related skills

Structure

Rule 1 (MUST): One top-level RSpec.describe block per class

Use the class constant directly:

RSpec.describe Git::CommandLine::Capturing do

Never use a string in place of the constant, even for backward-compat aliases:

# Bad — string describe; described_class is unavailable, coverage tooling may not
# map the spec to the source file, and typos go undetected at load time.
RSpec.describe 'Git::CommandLineResult' do

If the constant is a backward-compat alias (e.g. Git::CommandLineResult = Git::CommandLine::Result), use the alias constant itself as the describe argument — the alias is a real Ruby constant and loads without issue. The test content should verify that the alias points to the correct target using object identity (be), which would not be caught implicitly by a NameError on the canonical constant:

RSpec.describe Git::CommandLineResult do
  it 'is a backward-compatible alias for Git::CommandLine::Result' do
    expect(described_class).to be(Git::CommandLine::Result)
  end
end

Do not test #initialize or other behavior here — that is already covered by the spec for the canonical class.

Rule 2 (MUST): One describe block per public method

Use #method_name for instance methods and .method_name for class methods. Include #initialize:

describe '#call' do ...
describe '.build' do ...
describe '#initialize' do ...

Inherited #initialize in concrete subclasses (SHOULD): If a class is directly instantiated by callers but does not override #initialize, its spec SHOULD still include a describe '#initialize' block using the minimal have_attributes form (see Rule 13). This serves two purposes:

  1. The spec is self-contained documentation of the constructor signature — a reader does not need to consult the ancestor's spec to know what arguments the class accepts or what attributes it exposes.
  2. It guards against an accidental def initialize override in the subclass that silently drops or misroutes an argument, which the ancestor's spec would not catch.

Omit the inherited #initialize block only for abstract or internal classes that callers never instantiate directly — those are sufficiently covered by the ancestor's spec alone.

Rule 3 (SHOULD): Add # frozen_string_literal: true at the top of every spec file

Matches project-wide convention and catches accidental string mutation.

Rule 4 (MUST): Spec file location must mirror source file location

lib/git/foo/bar.rb maps to spec/unit/git/foo/bar_spec.rb. Deviating from this makes specs hard to find and breaks coverage mapping.

Rule 5 (MUST): require 'spec_helper' and only the file(s) under test

Every unit spec MUST start with require 'spec_helper', then require only the Ruby file(s) it directly tests. Avoid requiring unrelated libraries or classes — doing so creates false coupling where a rename or move breaks specs that don't even test that class.

Rule 6 (MUST): Test only through the public interface

Never call private methods directly in tests. If private logic is hard to reach through the public interface, stop and propose one of these remedies to the user:

  • Extract a class — move the logic to a new class with its own public interface.
  • Make the method public — promote it if it is genuinely part of the contract.
  • Redesign the public API — split the public method into smaller public steps.

Never use send, instance_variable_get, or __send__ to reach private state.

Naming and Organization

Ru


Content truncated.

When not to use it

  • Integration or E2E testing
  • Legacy spec cleanup without plan

Prerequisites

bundle

Limitations

  • Requires manual verification of MUST rules
  • Legacy specs may require incremental cleanup

How it compares

Unlike generic linting, this skill enforces project-specific RSpec architectural rules like described_class usage and branch coverage thresholds.

Compared to similar skills

rspec-unit-testing-standards side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
rspec-unit-testing-standards (this skill)03moReviewIntermediate
ruby-coder55moNo flagsIntermediate
rails-testing18moNo flagsBeginner
ruby-pro14moNo flagsAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry