Use when writing Rails tests - enforces fixtures-only, integration-style controller tests, Current context setup, simple naming, and Minitest syntax
View on GitHubZempTime/zemptime-marketplace
vanilla-rails
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/ZempTime/zemptime-marketplace/blob/main/vanilla-rails/skills/testing/SKILL.md -a claude-code --skill vanilla-rails-testingInstallation paths:
.claude/skills/vanilla-rails-testing/# Vanilla Rails Testing
**Counter-intuitive patterns from 37signals.** These are NOT standard Rails community practices.
**Core principle:** Fixtures over factories. Always. Integration tests for controllers. Minitest, not RSpec.
## The Iron Law
**NO FACTORYBOT. NO RSPEC. NO DATA CREATION IN TESTS.**
If you write `create(:model)`, `FactoryBot`, `let`, `describe`, `it`, `expect`, or `before_each` → DELETE IT.
## Fixtures Only
```ruby
# ✅ GOOD - Reference fixtures
test "close card" do
cards(:logo).close
assert cards(:logo).closed?
end
# ❌ BAD - Never create data
test "close card" do
card = create(:card) # DELETE THIS
card.close
end
# ❌ BAD - Never use FactoryBot
let(:card) { create(:card) } # DELETE THIS
# ❌ BAD - Never use RSpec
describe Card do # DELETE THIS
it "closes" do # DELETE THIS
```
**Reference fixtures by symbol:** `cards(:logo)`, `users(:david)`, `boards(:writebook)`, `sessions(:kevin)`
**Why fixtures?** They're real data, loaded once, fast, and force you to think about realistic scenarios.
**Q: What if the fixture I need doesn't exist?**
**A:** Add it to the fixtures file. Never create data in tests.
## Controller Tests Use Integration Style
```ruby
# ✅ GOOD - ActionDispatch::IntegrationTest
class Cards::ClosuresControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in_as :kevin
end
test "create" do
post card_closure_path(cards(:logo)), as: :turbo_stream
assert_response :success
end
end
# ❌ BAD - Never use ActionController::TestCase
class Cards::ClosuresControllerTest < ActionController::TestCase # DELETE THIS
post :create, params: { card_id: card.id } # DELETE THIS
end
```
**Why integration style?** Tests the full request cycle including routing, middleware, and response rendering.
## Model Tests Require Current.session
```ruby
# ✅ GOOD - Set Current.session in setup
class Card::CloseableTest < ActiveSupport::TestCase
setup do
Current.session = sessions(:david)
end
test "close rIssues Found: