Rails TDD Standards

RSpec testing standards and best practices for Rails applications. Use when writing new tests, reviewing test quality, debugging factory errors, setting up F...

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 31 · 1 current installs · 1 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name and description match the content: RSpec/FactoryBot/Cabybara guidance and test-running examples. The only required binary is 'bundle', which is appropriate for running RSpec in a Ruby/Rails project.
Instruction Scope
SKILL.md stays within testing best-practices and includes examples and shell snippets (e.g., bundle exec rspec, and an example wget/tar install for geckodriver). These snippets are documentation-style guidance rather than directives to exfiltrate data. Important caveat: the skill recommends running test commands (bundle exec rspec), and running a project's test suite executes that project's code — which can run arbitrary code from that repository. Also some snippets show downloading a binary from a GitHub release; users should verify such commands before executing them.
Install Mechanism
There is no install spec and no code files that would be written to disk at install time. The skill is instruction-only, which minimizes install-time risk.
Credentials
The skill requests no environment variables or credentials. Examples reference test framework configuration (e.g., WebMock.disable_net_connect!), which is expected for test guidance and does not indicate hidden credential access.
Persistence & Privilege
always is false and the skill is user-invocable. It does not request persistent system changes or modify other skills' configs. Autonomous invocation is allowed by platform default but the skill itself does not ask for elevated persistence.
Assessment
This skill is a documentation-only helper for Rails testing and appears coherent. Before you follow any provided shell commands: (1) Don't blindly run wget/tar commands — verify the release URL and checksum; (2) Be aware that running 'bundle exec rspec' executes code from your project and its test suite, so only run tests in a trusted environment; (3) The snippets that disable WebMock or install browser drivers are normal for system tests but change test-networking behavior and add binaries to your user path — review them before executing. Overall this skill is safe as read-only guidance, but exercise the usual caution when executing shell commands it documents.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.1
Download zip
latestvk977nw1pnfdn392q1v22108w458373a2

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

🧪 Clawdis
OSLinux · macOS · Windows
Binsbundle

SKILL.md

Rails TDD Standards

Best practices for writing clean, reliable RSpec tests in Rails applications.

Core Principle: Single Expectation

One assertion per test. Tests should read like specifications — each it block verifies exactly one thing.

# ✅ Correct
it { is_expected.to validate_presence_of(:email) }
it { is_expected.to belong_to(:user) }

# ❌ Wrong — too many expectations in one test
it "validates the user" do
  expect(user).to validate_presence_of(:email)
  expect(user).to validate_presence_of(:name)
  expect(user).to be_valid
end

FactoryBot Patterns

Always use role traits

# ✅ Correct
create(:user, :admin)
create(:user, :driver)
create(:user, :patron)

# ❌ Wrong — missing role context
create(:user)

Association keys matter

Check your factory definitions carefully. Wrong keys cause silent failures.

# ✅ Example — if your factory uses owner:
create(:profile, owner: user)

# ❌ Wrong key
create(:profile, user: user)  # fails if factory expects owner:

Always set required associations

When a model requires a specific association to be valid, always set it explicitly — don't rely on factory defaults when they might be nil or wrong.

# ✅ Explicit — clear intent, no surprises
let(:record) do
  create(:model, required_association: other_record)
end

# ❌ Implicit — may break if factory default changes
let(:record) { create(:model) }

Use described_class not hardcoded class names

# ✅
subject { described_class.new(params) }

# ❌
subject { MyService.new(params) }

Common FactoryBot Gotchas

Join tables without primary key

Tables with id: false can't use .last or .first.

# ✅ Use a scoped query
record = JoinModel.find_by(field_a: a, field_b: b)

# ❌ Will raise ActiveRecord::MissingRequiredOrderError
record = JoinModel.last

RecordInvalid from missing role/trait

If you see Validation failed: X must have Y role — you're missing a trait on the user factory.

# ✅
user = create(:user, :driver)

# ❌ causes "must be a driver" validation error
user = create(:user)

Spec Structure

RSpec.describe MyClass do
  # Subject
  subject(:instance) { described_class.new(params) }

  # Shared setup
  let(:user) { create(:user, :admin) }

  # Group by behavior
  describe "#method_name" do
    context "when condition is true" do
      it "does the expected thing" do
        expect(instance.method_name).to eq(expected)
      end
    end

    context "when condition is false" do
      it "does something else" do
        expect(instance.method_name).to be_nil
      end
    end
  end
end

Mocking & Stubbing

# Stub a method
allow(object).to receive(:method_name).and_return(value)

# Stub and verify it was called
expect(object).to receive(:method_name).once

# Stub HTTP calls (WebMock)
stub_request(:post, "https://api.example.com/endpoint")
  .to_return(status: 200, body: { result: "ok" }.to_json)

# Allow localhost for system tests (if using WebMock)
WebMock.disable_net_connect!(allow_localhost: true)

Service Object Testing

RSpec.describe MyService do
  describe "#call" do
    context "with valid params" do
      it "returns the expected result" do
        result = described_class.new(valid_params).call
        expect(result).to be_a(ExpectedClass)
      end

      it "creates the expected record" do
        expect { described_class.new(valid_params).call }
          .to change(Record, :count).by(1)
      end
    end

    context "with invalid params" do
      it "returns false" do
        expect(described_class.new(invalid_params).call).to be(false)
      end
    end
  end
end

Running Tests

# Run full suite
bundle exec rspec

# Run specific file
bundle exec rspec spec/models/user_spec.rb

# Run specific line
bundle exec rspec spec/models/user_spec.rb:42

# Run only failures from last run
bundle exec rspec --only-failures

# Run with documentation format
bundle exec rspec --format documentation

See Also

  • references/factory-patterns.md — advanced FactoryBot patterns
  • references/system-specs.md — Capybara / browser testing setup

Files

3 total
Select a file
Select a file to preview.

Comments

Loading comments…