From ruby-skills
Avoids NoMethodError in Ruby tests by detailing minitest vs test-unit divergences in assertion names, unique methods, lifecycle hooks, and CLI test selection flags.
npx claudepluginhub st0012/ruby-skills --plugin ruby-skillsThis skill uses the workspace's default tool permissions.
Only covers where minitest and test-unit diverge. If something isn't listed here, it works the same in both.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Only covers where minitest and test-unit diverge. If something isn't listed here, it works the same in both.
Using the wrong name causes NoMethodError.
| Concept | minitest | test-unit |
|---|---|---|
| Exception | assert_raises (plural) | assert_raise (singular) |
| Throw | assert_throws (plural) | assert_throw (singular) |
| Collection inclusion | assert_includes (plural) | assert_include (singular) |
| Path exists | assert_path_exists (with s) | assert_path_exist (no s) |
| Negation pattern | refute_* (e.g. refute_nil) | assert_not_* (e.g. assert_not_nil) |
test-unit aliases minitest names (assert_raises, refute_*, etc.), so minitest syntax works in test-unit but not vice versa.
| Method | Purpose |
|---|---|
assert_nothing_raised | Passes if block doesn't raise (also added by Rails on top of minitest) |
assert_true / assert_false | Checks for exactly true or false (not just truthy/falsy) |
assert_boolean | Checks value is true or false |
assert_compare | For <, <=, >, >= comparisons |
assert_raise_with_message | Checks both exception class and message |
assert_raise_message | Checks exception message only (any class) |
assert_raise_kind_of | Checks exception via kind_of? instead of exact class |
assert_const_defined / assert_not_const_defined | Check constant existence |
assert_alias_method | Verify method aliasing |
assert_nothing_thrown | Passes if block doesn't call throw |
assert_block | Passes if block returns truthy |
| Method | Purpose |
|---|---|
assert_pattern / refute_pattern | Ruby 3+ pattern matching (in expressions) |
assert_silent | Passes if block produces no stdout/stderr |
assert_output | Check stdout/stderr content |
capture_io / capture_subprocess_io | Capture output for inspection |
skip_until(y, m, d, msg) | Skip until a date, then fail as reminder |
fail_after(y, m, d, msg) | Pass until a date, then fail as reminder |
assert_equal(nil, value) is a hard failure in minitest 6. Use assert_nil(value) instead. test-unit has no such restriction.
| Operation | minitest | test-unit |
|---|---|---|
| By name (exact) | -n test_method_name | --name test_method_name |
| By name (regex) | -n /pattern/ | --name "/pattern/" |
| By name (rake) | N=/pattern/ rake test | N/A |
| By line number | m test/file.rb:42 or minitest test/file.rb:42 (v6) | --location path.rb:LINE |
| By line (Rails) | bin/rails test test/file.rb:42 | N/A |
| Exclude by name | -e /pattern/ | --ignore-name /pattern/ |
| Exclude by class | N/A | --ignore-testcase /pattern/ |
| Filter by class | N/A (use -n /ClassName#/) | --testcase ClassName |
| Filter by attribute | N/A | --attribute "speed == :slow" |
| Seed | -s SEED or --seed SEED | N/A (use --order random) |
| Stop on failure | N/A | --stop-on-failure |
| Execution order | Random by default | --order alphabetic / random / defined |
| Color | -p (pride) | --color-scheme SCHEME |
minitest 6 renamed -n to -i (--include). -n still works as an alias but is planned for removal.
bin/rails test adds: -b (full backtrace), -f (fail-fast), -d (defer output), --profile [N] (slowest tests).
before_setup (for frameworks like Rails)
setup (for test authors)
after_setup
[TEST]
before_teardown
teardown
after_teardown
No class-level hooks. No cleanup. For before(:all) / after(:all), use the minitest-hooks gem.
startup (class method, once before all tests)
setup (instance, before each test)
[TEST]
cleanup (instance, only if test didn't raise)
teardown (instance, always runs, even if cleanup raised)
shutdown (class method, once after all tests)
startup/shutdown have no minitest equivalent. cleanup runs after a passing test but before it's marked as passed — use it for verification like mock expectations. teardown always runs regardless of outcome — use it for resource release.
test-unit also supports registering multiple setup/teardown methods by symbol:
setup :prepare_database, :prepare_cache
| Concept | minitest | test-unit |
|---|---|---|
| Skip a test | skip("reason") | omit("reason") or pend("reason") |
| Conditional skip | skip("reason") if condition | omit("reason") if condition or omit_if(condition, "reason") / omit_unless(condition, "reason") |
| Output character | S | O (omit) or P (pend) |
Critical difference: test-unit's pend with a block fails if the block passes. This catches code that was fixed but still marked pending. minitest's skip is always unconditional.
# test-unit: this FAILS if the bug gets fixed
pend("Bug #123") do
assert_equal(42, buggy_method) # if this passes, test fails
end
# minitest: no equivalent behavior
skip("Bug #123") # always skips, no block form
| Aspect | minitest | test-unit |
|---|---|---|
| Progress | .FES | .FEOPN (adds Omit, Pending, Notification) |
| Summary | N runs, N assertions, N failures, N errors, N skips | N tests, N assertions, N failures, N errors, N pendings, N omissions, N notifications |
| Throughput | runs/s, assertions/s | tests/s, assertions/s |
These have no minitest equivalent:
data("label", value) method generates parameterized test runspriority :must / :important / :high / :normal / :low / :never with probabilistic execution--attributesub_test_case: Named nested test groups (minitest uses describe blocks in Spec mode)notify: Non-fatal informational messages shown as N in output~/.test-unit.yml for persistent settingsRails uses minitest, not test-unit. But Rails adds aliases and methods that blur the line:
Aliases Rails defines on top of minitest:
| Rails alias | Delegates to | Effect |
|---|---|---|
assert_not_* (12 methods) | refute_* | assert_not_nil, assert_not_equal, etc. all work in Rails |
assert_not | refute | Base negation |
assert_raise (singular) | assert_raises | Both singular and plural work in Rails |
assert_no_match | refute_match |
Methods Rails adds (not in either framework):
| Method | Purpose |
|---|---|
assert_nothing_raised | Passes if block doesn't raise |
assert_difference / assert_no_difference | Check numeric change after block |
assert_changes / assert_no_changes | Check value change after block |
This means in Rails: assert_not_nil, assert_raise, and assert_nothing_raised all work — but they will not work if you move the test to plain minitest outside Rails.