Claude Code Plugins

Community-maintained marketplace

Feedback

This skill should be used when the user asks about "Minitest", "Rails testing", "test/", "fixtures", "ActiveSupport::TestCase", "ActionDispatch::IntegrationTest", "system tests", "functional tests", "assert", "assert_equal", "assert_difference", "test_helper", "rails test", or needs guidance on testing Rails applications with the default Minitest framework.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name minitest
description This skill should be used when the user asks about "Minitest", "Rails testing", "test/", "fixtures", "ActiveSupport::TestCase", "ActionDispatch::IntegrationTest", "system tests", "functional tests", "assert", "assert_equal", "assert_difference", "test_helper", "rails test", or needs guidance on testing Rails applications with the default Minitest framework.
version 1.0.0

Minitest for Rails

Comprehensive guide to testing Rails applications with Minitest, the default Rails testing framework.

Test Case Classes

Rails provides specialized test case base classes:

Base Class Purpose Location
ActiveSupport::TestCase Model and unit tests test/models/
ActionDispatch::IntegrationTest Multi-controller workflow tests test/integration/
ActionDispatch::SystemTestCase Browser-based end-to-end tests test/system/
ActionController::TestCase Functional controller tests test/controllers/
ActionView::TestCase View and helper tests test/helpers/
ActionMailer::TestCase Mailer tests test/mailers/
ActiveJob::TestCase Background job tests test/jobs/

Configuration

# test/test_helper.rb
ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rails/test_help"

class ActiveSupport::TestCase
  # Run tests in parallel
  parallelize(workers: :number_of_processors)

  # Load fixtures
  fixtures :all

  # Add helper methods here
end

Directory Structure

test/
├── controllers/          # Functional controller tests
├── fixtures/
│   ├── files/           # Upload test files
│   ├── users.yml
│   └── articles.yml
├── helpers/             # View helper tests
├── integration/         # Multi-controller tests
├── jobs/                # ActiveJob tests
├── mailers/             # Email tests
├── models/              # Model unit tests
├── system/              # Browser tests (Capybara)
├── application_system_test_case.rb
└── test_helper.rb

Model Tests

# test/models/article_test.rb
require "test_helper"

class ArticleTest < ActiveSupport::TestCase
  # Setup runs before each test
  setup do
    @article = articles(:published)
  end

  # Associations
  test "belongs to user" do
    assert_respond_to @article, :user
    assert_instance_of User, @article.user
  end

  test "has many comments" do
    assert_respond_to @article, :comments
  end

  # Validations
  test "is invalid without title" do
    article = Article.new(body: "Content", user: @user)
    assert_not article.valid?
    assert_includes article.errors[:title], "can't be blank"
  end

  test "is invalid with title over 255 characters" do
    article = Article.new(title: "a" * 256, body: "Content", user: @user)
    assert_not article.valid?
  end

  test "is valid with all attributes" do
    article = Article.new(title: "Test", body: "Content", user: @user)
    assert article.valid?
  end

  # Scopes
  test ".published returns only published articles" do
    assert_includes Article.published, articles(:published)
    assert_not_includes Article.published, articles(:draft)
  end

  test ".recent orders by created_at descending" do
    recent = Article.recent.first
    assert_equal articles(:published), recent
  end

  # Instance methods
  test "#publish! changes status to published" do
    article = articles(:draft)
    article.publish!

    assert_equal "published", article.status
    assert_not_nil article.published_at
  end

  test "#published? returns true for published articles" do
    assert articles(:published).published?
    assert_not articles(:draft).published?
  end
end

Controller Tests (Functional)

# test/controllers/articles_controller_test.rb
require "test_helper"

class ArticlesControllerTest < ActionDispatch::IntegrationTest
  setup do
    @article = articles(:published)
    @user = users(:one)
  end

  test "should get index" do
    get articles_url
    assert_response :success
  end

  test "should get show" do
    get article_url(@article)
    assert_response :success
  end

  test "should get new" do
    get new_article_url
    assert_response :success
  end

  test "should create article" do
    assert_difference("Article.count") do
      post articles_url, params: {
        article: { title: "New Article", body: "Content" }
      }
    end

    assert_redirected_to article_url(Article.last)
  end

  test "should not create article with invalid params" do
    assert_no_difference("Article.count") do
      post articles_url, params: { article: { title: "" } }
    end

    assert_response :unprocessable_entity
  end

  test "should update article" do
    patch article_url(@article), params: {
      article: { title: "Updated Title" }
    }

    assert_redirected_to article_url(@article)
    @article.reload
    assert_equal "Updated Title", @article.title
  end

  test "should destroy article" do
    assert_difference("Article.count", -1) do
      delete article_url(@article)
    end

    assert_redirected_to articles_url
  end
end

Integration Tests

# test/integration/user_flows_test.rb
require "test_helper"

class UserFlowsTest < ActionDispatch::IntegrationTest
  test "user can create article" do
    get new_article_url
    assert_response :success

    post articles_url, params: {
      article: { title: "My First Article", body: "Content" }
    }
    follow_redirect!
    assert_select "h1", "My First Article"
  end

  test "browsing articles as guest" do
    get articles_url
    assert_response :success
    assert_select "article", minimum: 1

    get article_url(articles(:published))
    assert_response :success
    assert_select "h1", articles(:published).title
  end
end

System Tests

# test/application_system_test_case.rb
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
end
# test/system/articles_test.rb
require "application_system_test_case"

class ArticlesTest < ApplicationSystemTestCase
  setup do
    @article = articles(:published)
  end

  test "visiting the index" do
    visit articles_url
    assert_selector "h1", text: "Articles"
  end

  test "creating an article" do
    visit new_article_url

    fill_in "Title", with: "System Test Article"
    fill_in "Body", with: "This is test content."
    click_on "Create Article"

    assert_text "Article was successfully created"
    assert_text "System Test Article"
  end

  test "updating an article" do
    visit article_url(@article)
    click_on "Edit"

    fill_in "Title", with: "Updated Title"
    click_on "Update Article"

    assert_text "Article was successfully updated"
    assert_text "Updated Title"
  end

  test "destroying an article" do
    visit article_url(@article)
    click_on "Delete", match: :first

    assert_text "Article was successfully destroyed"
  end

  test "adding comment with Turbo" do
    visit article_url(@article)

    fill_in "comment_body", with: "Great article!"
    click_on "Add Comment"

    within "#comments" do
      assert_text "Great article!"
    end
  end
end

Fixtures

# test/fixtures/users.yml
one:
  email: user1@example.com
  name: Test User

admin:
  email: admin@example.com
  name: Admin User
  role: admin

# test/fixtures/articles.yml
published:
  title: Published Article
  body: This is published content.
  status: published
  user: one
  published_at: <%= 1.day.ago %>
  created_at: <%= 2.days.ago %>

draft:
  title: Draft Article
  body: This is draft content.
  status: draft
  user: one
  created_at: <%= 1.day.ago %>

# With associations
# test/fixtures/comments.yml
one:
  body: Great article!
  article: published
  user: one

Assertions Reference

Basic Assertions

assert value                        # truthy
assert_not value                    # falsy (Rails)
refute value                        # falsy (Minitest)

assert_equal expected, actual       # ==
assert_not_equal unexpected, actual
assert_same expected, actual        # same object
assert_nil value
assert_not_nil value

assert_empty collection
assert_not_empty collection
assert_includes collection, item
assert_not_includes collection, item

assert_instance_of Class, object
assert_kind_of Class, object
assert_respond_to object, :method

assert_match /regex/, string
assert_no_match /regex/, string

assert_raises(ErrorClass) { action }
assert_nothing_raised { action }

Rails-Specific Assertions

# Count changes
assert_difference "Article.count", 1 do
  post articles_url, params: { article: valid_params }
end

assert_no_difference "Article.count" do
  post articles_url, params: { article: invalid_params }
end

# Multiple counts
assert_difference ["Article.count", "Tag.count"], 1 do
  post articles_url, params: params_with_tag
end

# HTTP responses
assert_response :success         # 200
assert_response :redirect        # 3xx
assert_response :not_found       # 404
assert_response :unprocessable_entity  # 422
assert_response 201              # Specific code

# Redirects
assert_redirected_to article_url(@article)
assert_redirected_to root_url

# Query count (prevent N+1)
assert_queries_count(2) do
  Article.includes(:user).each { |a| a.user.name }
end

# Enqueued jobs
assert_enqueued_jobs 1 do
  ArticleMailer.published(@article).deliver_later
end

assert_enqueued_with(job: NotifyJob, args: [@article]) do
  @article.publish!
end

# Enqueued emails
assert_enqueued_emails 1 do
  UserMailer.welcome(@user).deliver_later
end

# DOM assertions (system tests)
assert_selector "h1", text: "Title"
assert_text "Expected content"
assert_no_text "Should not appear"
assert_select "article", count: 3

Mailer Tests

# test/mailers/user_mailer_test.rb
require "test_helper"

class UserMailerTest < ActionMailer::TestCase
  test "welcome email" do
    user = users(:one)
    email = UserMailer.welcome(user)

    assert_emails 1 do
      email.deliver_now
    end

    assert_equal ["welcome@example.com"], email.from
    assert_equal [user.email], email.to
    assert_equal "Welcome to Our App", email.subject
    assert_match "Hello #{user.name}", email.body.encoded
  end

  test "welcome email is enqueued" do
    user = users(:one)

    assert_enqueued_emails 1 do
      UserMailer.welcome(user).deliver_later
    end
  end
end

Job Tests

# test/jobs/article_notification_job_test.rb
require "test_helper"

class ArticleNotificationJobTest < ActiveJob::TestCase
  test "sends notification to subscribers" do
    article = articles(:published)

    assert_enqueued_emails article.subscribers.count do
      ArticleNotificationJob.perform_now(article)
    end
  end

  test "job is enqueued on publish" do
    article = articles(:draft)

    assert_enqueued_with(job: ArticleNotificationJob, args: [article]) do
      article.publish!
    end
  end

  test "performs enqueued jobs" do
    article = articles(:draft)
    article.publish!

    perform_enqueued_jobs

    # Verify side effects
    assert_emails article.subscribers.count
  end
end

Helper Tests

# test/helpers/articles_helper_test.rb
require "test_helper"

class ArticlesHelperTest < ActionView::TestCase
  test "format_status returns badge HTML" do
    result = format_status("published")
    assert_dom_equal '<span class="badge badge-success">Published</span>', result
  end

  test "reading_time calculates minutes" do
    article = articles(:published)
    article.body = "word " * 500  # 500 words

    assert_equal "2 min read", reading_time(article)
  end
end

Parallel Testing

# test/test_helper.rb
class ActiveSupport::TestCase
  # Run tests in parallel with specified workers
  parallelize(workers: :number_of_processors)

  # Or with specific count
  parallelize(workers: 4)

  # Setup for parallel testing
  parallelize_setup do |worker|
    # Setup for each worker
  end

  parallelize_teardown do |worker|
    # Cleanup for each worker
  end
end

Running Tests

# All tests
rails test

# Specific directory
rails test test/models

# Single file
rails test test/models/article_test.rb

# Single test by line number
rails test test/models/article_test.rb:25

# Single test by name
rails test test/models/article_test.rb -n test_is_invalid_without_title

# System tests only
rails test:system

# All including system
rails test:all

# Parallel execution
rails test:parallel:all

# With verbose output
rails test -v

# Stop on first failure
rails test -f

# Specific seed (for reproducibility)
rails test --seed 12345

Additional Resources

Reference Files

  • references/minitest-patterns.md - Advanced patterns, custom assertions, test organization