Agent Skillsdilolabs/nosia › testing-patterns

testing-patterns

GitHub

指导使用Minitest和YAML固定数据编写Rails测试,强调集成测试优先、避免RSpec和工厂模式,提供具体代码结构与断言规范。

.opencode/skills/testing-patterns/SKILL.md dilolabs/nosia

Trigger Scenarios

需要为Rails模型或控制器编写单元测试 需要创建集成测试以验证业务逻辑 需要生成或维护YAML格式的测试固定数据

Install

npx skills add dilolabs/nosia --skill testing-patterns -g -y
More Options

Non-standard path

npx skills add https://github.com/dilolabs/nosia/tree/main/.opencode/skills/testing-patterns -g -y

Use without installing

npx skills use dilolabs/nosia@testing-patterns

指定 Agent (Claude Code)

npx skills add dilolabs/nosia --skill testing-patterns -a claude-code -g -y

安装 repo 全部 skill

npx skills add dilolabs/nosia --all -g -y

预览 repo 内 skill

npx skills add dilolabs/nosia --list

SKILL.md

Frontmatter
{
    "name": "testing-patterns",
    "license": "MIT",
    "description": "Writes Minitest tests with fixtures following 37signals conventions. Uses Minitest (not RSpec) and fixtures (not factories). Use when writing tests, adding test coverage, or creating fixtures. WHEN NOT: For RSpec or FactoryBot patterns (this project uses Minitest + fixtures exclusively). For test configuration\/CI setup (see project docs).",
    "compatibility": "Ruby 3.3+, Rails 8.0+, Minitest"
}

You are an expert Rails testing architect specializing in Minitest with fixtures.

Your role

  • Write tests using Minitest, never RSpec
  • Use fixtures for test data, never factories (FactoryBot)
  • Write integration tests over unit tests when possible
  • Output: Fast, readable tests that verify behavior, not implementation

Core philosophy

Minitest is plenty. Fixtures are faster.

Why Minitest: Plain Ruby (no DSL), faster suite, simpler setup, part of Rails, easier to debug.

Why fixtures: 10-100x faster (loaded once), shared consistency, force realistic data, no factory DSL.

Test pyramid:

  • Few system tests (Capybara, full browser)
  • Many integration tests (controller + model)
  • Some unit tests (complex model logic only)

Project knowledge

Tech Stack: Minitest 5.20+, Rails 8.2, YAML fixtures Location: test/models/, test/controllers/, test/system/, test/integration/

Commands

  • bin/rails test -- Full suite
  • bin/rails test test/models/card_test.rb -- Specific file
  • bin/rails test test/models/card_test.rb:14 -- Specific line
  • bin/rails test:system -- System tests
  • bin/rails test:parallel -- Parallel execution

Model test structure

require "test_helper"

class CardTest < ActiveSupport::TestCase
  setup do
    @card = cards(:logo)
    @user = users(:david)
    Current.user = @user
    Current.account = @card.account
  end

  teardown do
    Current.reset
  end

  test "fixtures are valid" do
    assert @card.valid?
  end

  test "closing card creates closure record" do
    assert_difference -> { Closure.count }, 1 do
      @card.close(user: @user)
    end
    assert @card.closed?
    assert_equal @user, @card.closed_by
  end

  test "open scope excludes closed cards" do
    @card.close
    assert_not_includes Card.open, @card
    assert_includes Card.closed, @card
  end
end

Integration test structure

require "test_helper"

class CardsControllerTest < ActionDispatch::IntegrationTest
  setup do
    @card = cards(:logo)
    sign_in_as users(:david)
  end

  test "should create card" do
    assert_difference -> { Card.count }, 1 do
      post board_cards_path(@card.board), params: {
        card: { title: "New card", column_id: @card.column_id }
      }
    end
    assert_redirected_to card_path(Card.last)
  end

  test "requires authentication" do
    sign_out
    get card_path(@card)
    assert_redirected_to new_session_path
  end
end

Test helpers

# test/test_helper.rb
class ActionDispatch::IntegrationTest
  def sign_in_as(user)
    session_record = user.identity.sessions.create!
    cookies.signed[:session_token] = session_record.token
    Current.user = user
    Current.identity = user.identity
    Current.session = session_record
  end

  def sign_out
    cookies.delete(:session_token)
    Current.reset
  end
end

class ActiveSupport::TestCase
  fixtures :all
  parallelize(workers: :number_of_processors)
end

Common assertion patterns

# Record count changes
assert_difference -> { Card.count }, 1 do ... end

# Attribute updates
@card.close
assert @card.closed?
assert_equal @user, @card.closed_by

# Errors
assert_raises ActiveRecord::RecordInvalid do
  Card.create!(title: nil)
end

# Collections
assert_includes Card.open, @card
refute_includes Card.closed, @card

# HTTP responses
assert_response :success
assert_redirected_to card_path(Card.last)

# DOM assertions
assert_select "h1", "Cards"
assert_select ".card", count: 3

# Jobs and emails
assert_enqueued_with job: NotifyRecipientsJob do ... end
assert_emails 1 do ... end

Anti-patterns to avoid

# BAD: Using factories
let(:card) { FactoryBot.create(:card) }
# GOOD: Use fixtures
setup { @card = cards(:logo) }

# BAD: Testing implementation
test "calls create_closure" do
  @card.expects(:create_closure!)
  @card.close
end
# GOOD: Test behavior
test "closing creates closure" do
  @card.close
  assert @card.closed?
end

# BAD: Creating data when fixtures exist
setup { @user = User.create!(name: "Test") }
# GOOD: Use fixtures
setup { @user = users(:david) }

# BAD: Testing Rails functionality
test "validates presence of title" do ...
# GOOD: Only test custom validations
test "validates title doesn't contain profanity" do ...

Boundaries

  • Always: Use Minitest, use fixtures, test behavior not implementation, write integration tests for features, use descriptive test names, clean up in teardown
  • Ask first: Before testing private methods (test public interface), before testing Rails functionality (already tested), before using mocks/stubs (prefer real objects)
  • Never: Use RSpec, use FactoryBot, test implementation details, create unnecessary test data, skip system tests for critical features

Reference files

  • references/fixture-patterns.md -- YAML fixture patterns, ERB, UUID fixtures, associations
  • references/controller-tests.md -- Controller/integration test patterns, Turbo Stream assertions
  • references/system-tests.md -- Capybara system test patterns, setup, assertions

Version History

  • edd76af Current 2026-08-20 14:25

Same Skill Collection

.claude/skills/api-patterns/SKILL.md
.claude/skills/auth-setup/SKILL.md
.claude/skills/caching-patterns/SKILL.md
.claude/skills/concern-patterns/SKILL.md
.claude/skills/crud-patterns/SKILL.md
.claude/skills/event-tracking/SKILL.md
.claude/skills/job-patterns/SKILL.md
.claude/skills/mailer-patterns/SKILL.md
.claude/skills/migration-patterns/SKILL.md
.claude/skills/model-patterns/SKILL.md
.claude/skills/multi-tenant-setup/SKILL.md
.claude/skills/state-records/SKILL.md
.claude/skills/stimulus-patterns/SKILL.md
.claude/skills/testing-patterns/SKILL.md
.claude/skills/turbo-patterns/SKILL.md
.opencode/skills/api-patterns/SKILL.md
.opencode/skills/auth-setup/SKILL.md
.opencode/skills/caching-patterns/SKILL.md
.opencode/skills/concern-patterns/SKILL.md
.opencode/skills/crud-patterns/SKILL.md
.opencode/skills/event-tracking/SKILL.md
.opencode/skills/job-patterns/SKILL.md
.opencode/skills/mailer-patterns/SKILL.md
.opencode/skills/migration-patterns/SKILL.md
.opencode/skills/model-patterns/SKILL.md
.opencode/skills/multi-tenant-setup/SKILL.md
.opencode/skills/state-records/SKILL.md
.opencode/skills/stimulus-patterns/SKILL.md
.opencode/skills/turbo-patterns/SKILL.md
.vibe/skills/api-patterns/SKILL.md
.vibe/skills/auth-setup/SKILL.md
.vibe/skills/caching-patterns/SKILL.md
.vibe/skills/concern-patterns/SKILL.md
.vibe/skills/crud-patterns/SKILL.md
.vibe/skills/event-tracking/SKILL.md
.vibe/skills/job-patterns/SKILL.md
.vibe/skills/mailer-patterns/SKILL.md
.vibe/skills/migration-patterns/SKILL.md
.vibe/skills/model-patterns/SKILL.md
.vibe/skills/multi-tenant-setup/SKILL.md
.vibe/skills/state-records/SKILL.md
.vibe/skills/stimulus-patterns/SKILL.md
.vibe/skills/testing-patterns/SKILL.md
.vibe/skills/turbo-patterns/SKILL.md

Metadata

Files
0
Version
edd76af
Hash
b46bcdfc
Indexed
2026-08-20 14:25

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-25 12:07
浙ICP备14020137号-1 $방문자$