Files
gh-nbarthel-claudy-plugins-…/skills/rails-test-patterns/skill.md
2025-11-30 08:42:29 +08:00

4.6 KiB
Raw Blame History

name, description, auto_invoke, trigger_on, file_patterns, tags, priority, version
name description auto_invoke trigger_on file_patterns tags priority version
rails-test-patterns Ensures comprehensive test coverage following Rails testing best practices true
file_create
file_modify
**/spec/**/*_spec.rb
**/test/**/*_test.rb
rails
testing
rspec
minitest
coverage
tdd
2 2.0

Rails Test Patterns Skill

Automatically ensures test quality and comprehensive coverage.

What This Skill Does

Automatic Checks:

  • Test framework detection (RSpec vs Minitest)
  • AAA pattern (Arrange-Act-Assert)
  • Coverage thresholds (80%+ models, 70%+ controllers)
  • Factory usage over fixtures
  • No flaky tests (sleep, Time.now without freezing)

When It Activates:

  • Test files created or modified
  • New models/controllers added (ensures tests exist)

Test Quality Checks

1. AAA Pattern

Good:

RSpec.describe User do
  describe '#full_name' do
    it 'combines first and last name' do
      # Arrange
      user = User.new(first_name: 'John', last_name: 'Doe')

      # Act
      result = user.full_name

      # Assert
      expect(result).to eq('John Doe')
    end
  end
end

Skill Output (if violated):

⚠️  Test Pattern: AAA structure not clear
Location: spec/models/user_spec.rb:15
Recommendation: Separate Arrange, Act, Assert with comments

2. Framework Detection

Detects:

# RSpec
describe Model do
  it 'does something' do
    expect(value).to eq(expected)
  end
end

# Minitest
class ModelTest < ActiveSupport::TestCase
  test "does something" do
    assert_equal expected, value
  end
end

3. Factory Usage

Preferred:

# spec/factories/users.rb
FactoryBot.define do
  factory :user do
    email { Faker::Internet.email }
    name { Faker::Name.name }
  end
end

# In tests
user = create(:user)

Skill Output:

  Test Pattern: Consider using FactoryBot
Location: spec/models/post_spec.rb:8
Current: User.create(name: 'Test', email: 'test@example.com')
Recommendation: Define factory and use create(:user)

4. Coverage Thresholds

Checks:

  • Models: 80%+ coverage
  • Controllers: 70%+ coverage
  • Services: 90%+ coverage

Skill Output:

⚠️  Test Coverage: Below threshold
File: app/models/order.rb
Coverage: 65% (threshold: 80%)
Missing: #calculate_total, #apply_discount methods

Add tests for uncovered methods.

5. Flaky Test Detection

Problem:

# BAD
it 'expires after 1 hour' do
  user = create(:user)
  sleep(3601)  # ❌ Actual waiting
  expect(user.expired?).to be true
end

# GOOD
it 'expires after 1 hour' do
  user = create(:user)
  travel 1.hour do  # ✅ Time travel
    expect(user.expired?).to be true
  end
end

Skill Output:

❌ Test Anti-pattern: Using sleep in test
Location: spec/models/session_spec.rb:42
Issue: sleep() makes tests slow and flaky

Fix: Use time helpers
travel 1.hour do
  # assertions here
end

Test Types

Model Tests

Should test:

  • Validations
  • Associations
  • Scopes
  • Instance methods
  • Class methods

Example:

RSpec.describe Post, type: :model do
  describe 'validations' do
    it { should validate_presence_of(:title) }
    it { should validate_uniqueness_of(:slug) }
  end

  describe 'associations' do
    it { should belong_to(:user) }
    it { should have_many(:comments) }
  end

  describe '#published?' do
    it 'returns true when published_at is set' do
      post = build(:post, published_at: 1.day.ago)
      expect(post.published?).to be true
    end
  end
end

Request Tests

Should test:

  • HTTP status codes
  • Response body content
  • Authentication requirements
  • Authorization checks

Example:

RSpec.describe 'Posts API', type: :request do
  describe 'GET /api/v1/posts' do
    it 'returns all posts' do
      create_list(:post, 3)

      get '/api/v1/posts'

      expect(response).to have_http_status(:ok)
      expect(JSON.parse(response.body).size).to eq(3)
    end

    context 'when not authenticated' do
      it 'returns unauthorized' do
        get '/api/v1/posts'
        expect(response).to have_http_status(:unauthorized)
      end
    end
  end
end

Configuration

# .rails-testing.yml
coverage:
  models: 80
  controllers: 70
  services: 90

patterns:
  enforce_aaa: warning
  require_factories: info
  detect_flaky: error

framework:
  auto_detect: true
  prefer: rspec  # or minitest

References


This skill ensures your Rails app has comprehensive, maintainable test coverage.