一键导入
rails-testing
TDD and testing patterns for Rails applications using Minitest and fixtures. Use when writing tests, setting up test data, or debugging test failures.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
TDD and testing patterns for Rails applications using Minitest and fixtures. Use when writing tests, setting up test data, or debugging test failures.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Generate social media preview images (Open Graph) for Rails apps. Creates an OG image using the project's design system at /og-image, screenshots it at 1200x630, and configures meta tags in the layout head.
Remove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's comprehensive "Signs of AI writing" guide. Detects and fixes patterns including: inflated symbolism, promotional language, superficial -ing analyses, vague attributions, em dash overuse, rule of three, AI vocabulary words, negative parallelisms, and excessive conjunctive phrases.
This skill should be used when setting up or running the Ralph autonomous coding loop that iterates through stories, runs tests, commits, and logs learnings.
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Write Ruby and Rails code in DHH's 37signals style. Use when writing Rails code, creating models, controllers, or any Ruby file. Embodies REST purity, fat models, thin controllers, Current attributes, Hotwire patterns, and "clarity over cleverness."
Turbo and Stimulus patterns for Rails applications. Use when implementing interactivity, real-time updates, or frontend behavior without JavaScript frameworks.
基于 SOC 职业分类
| name | rails-testing |
| description | TDD and testing patterns for Rails applications using Minitest and fixtures. Use when writing tests, setting up test data, or debugging test failures. |
| trigger | test, minitest, fixture, assert, testing, spec, coverage, tdd |
Write tests BEFORE implementation.
1. RED → Write a failing test
2. GREEN → Write minimal code to pass
3. REFACTOR → Clean up, tests stay green
# Step 1: Write the test FIRST
test "user can close a card" do
card = cards(:open)
assert_not card.closed?
card.close
assert card.closed?
assert_equal users(:one), card.closure.closed_by
end
# Step 2: Run it - see it fail
# $ rails test test/models/card_test.rb:10
# Step 3: Implement minimal code to pass
# Step 4: Run it - see it pass
# Step 5: Refactor if needed
| When adding... | Write first... |
|---|---|
| Model method | Unit test for the method |
| Controller action | Integration test for endpoint |
| User feature | System test with Capybara |
| Bug fix | Test that reproduces the bug |
Describe behavior, not implementation:
# ✅ Good
test "closing a card creates a closure record"
test "user cannot close cards they don't own"
# ❌ Bad
test "close method calls create_closure!"
test "Closeable concern is included"
"Write tests for behavior, not implementation. Use fixtures, not factories."
Core Principles:
| Type | Location | Purpose |
|---|---|---|
| Unit | test/models/ | Model behavior |
| Controller | test/controllers/ | Request/response |
| Integration | test/integration/ | Multi-step flows |
| System | test/system/ | Browser tests |
| Mailer | test/mailers/ | Email content |
| Job | test/jobs/ | Background jobs |
# test/fixtures/users.yml
admin:
id: 01961a2a-c0de-7000-8000-000000000001
email: admin@example.com
name: Admin User
regular:
id: 01961a2a-c0de-7000-8000-000000000001
email: user@example.com
name: Regular User
# test/fixtures/boards.yml
main:
id: 01961a2a-c0de-7000-8000-000000000001
name: Main Board
owner: admin # References users(:admin)
# test/fixtures/cards.yml
open_card:
id: 01961a2a-c0de-7000-8000-000000000001
board: main # References boards(:main)
author: admin
title: Open Card
closed_card:
id: 01961a2a-c0de-7000-8000-000000000001
board: main
author: admin
title: Closed Card
# Closure record creates the closed state
# test/fixtures/cards.yml
<% 10.times do |i| %>
card_<%= i %>:
id: 01961a2a-c0de-7000-8000-000000000001
board: main
author: admin
title: Card <%= i %>
created_at: <%= i.days.ago %>
<% end %>
# test/fixtures/closures.yml
card_closure:
id: 01961a2a-c0de-7000-8000-000000000001
closeable: closed_card (Card) # Type in parentheses
closed_by: admin
# test/models/card_test.rb
class CardTest < ActiveSupport::TestCase
setup do
@card = cards(:open_card)
@user = users(:admin)
Current.user = @user
end
teardown do
Current.reset
end
test "belongs to board" do
assert_equal boards(:main), @card.board
end
test "can be closed" do
assert_not @card.closed?
@card.close
assert @card.closed?
assert_equal @user, @card.closure.closed_by
end
test "cannot close twice" do
@card.close
assert_raises(ActiveRecord::RecordInvalid) { @card.close }
end
test "open scope excludes closed cards" do
closed = cards(:closed_card)
assert_includes Card.open, @card
assert_not_includes Card.open, closed
end
end
# test/controllers/cards_controller_test.rb
class CardsControllerTest < ActionDispatch::IntegrationTest
setup do
@user = users(:admin)
@card = cards(:open_card)
sign_in @user
end
test "index shows cards" do
get cards_path
assert_response :success
assert_select "article.card", minimum: 1
end
test "show displays card" do
get card_path(@card)
assert_response :success
assert_select "h1", @card.title
end
test "create redirects to card" do
assert_difference "Card.count" do
post cards_path, params: {
card: { title: "New Card", board_id: boards(:main).id }
}
end
assert_redirected_to card_path(Card.last)
end
test "unauthorized user cannot create" do
sign_out
post cards_path, params: { card: { title: "Test" } }
assert_redirected_to new_session_path
end
end
# test/system/cards_test.rb
class CardsTest < ApplicationSystemTestCase
setup do
@user = users(:admin)
sign_in @user
end
test "creating a card" do
visit board_path(boards(:main))
click_on "New Card"
fill_in "Title", with: "System Test Card"
fill_in "Description", with: "Created via system test"
click_on "Create Card"
assert_text "System Test Card"
assert_text "Card was successfully created"
end
test "closing a card" do
card = cards(:open_card)
visit card_path(card)
click_on "Close Card"
assert_text "Card closed"
assert_selector ".badge", text: "Closed"
end
test "inline editing with Turbo" do
card = cards(:open_card)
visit card_path(card)
within turbo_frame("card_#{card.id}") do
click_on "Edit"
fill_in "Title", with: "Updated Title"
click_on "Save"
end
assert_text "Updated Title"
# Page didn't fully reload
assert_no_selector ".loading"
end
end
# test/test_helper.rb
class ActiveSupport::TestCase
parallelize(workers: :number_of_processors)
fixtures :all
# Sign in helper
def sign_in(user)
post session_path, params: { email: user.email }
follow_magic_link_for(user)
end
def sign_out
delete session_path
end
private
def follow_magic_link_for(user)
token = user.generate_token_for(:magic_link)
get verify_session_path(token: token)
end
end
# test/application_system_test_case.rb
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome
def sign_in(user)
visit new_session_path
fill_in "Email", with: user.email
click_on "Send Magic Link"
# In test, directly verify the token
token = user.generate_token_for(:magic_link)
visit verify_session_path(token: token)
end
end
# Equality
assert_equal expected, actual
assert_not_equal unexpected, actual
# Boolean
assert predicate
assert_not predicate
# Nil
assert_nil value
assert_not_nil value
# Collections
assert_includes collection, item
assert_empty collection
# Changes
assert_difference "Card.count", 1 do
# action
end
assert_no_difference "Card.count" do
# action
end
# Exceptions
assert_raises(ActiveRecord::RecordInvalid) { invalid_action }
# Response
assert_response :success
assert_redirected_to card_path(@card)
# HTML
assert_select "h1", "Expected Title"
assert_select "article.card", count: 5
# All tests
rails test
# Specific file
rails test test/models/card_test.rb
# Specific test by line
rails test test/models/card_test.rb:42
# By name pattern
rails test -n /close/
# Verbose output
rails test --verbose
# Fail fast
rails test --fail-fast
# System tests
rails test:system
# With coverage
COVERAGE=true rails test