SkillAgentSearch skills...

Minitest

minitest provides a complete suite of testing facilities supporting TDD, BDD, and benchmarking.

Install / Use

/learn @minitest/Minitest
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

= minitest/{test,spec,benchmark}

home :: https://minite.st/ code :: https://github.com/minitest/minitest bugs :: https://github.com/minitest/minitest/issues rdoc :: https://docs.seattlerb.org/minitest clog :: https://github.com/minitest/minitest/blob/master/History.rdoc emacs:: https://github.com/arthurnn/minitest-emacs vim :: https://github.com/vim-test/vim-test

== DESCRIPTION:

minitest provides a complete suite of testing facilities supporting TDD, BDD, and benchmarking.

"I had a class with Jim Weirich on testing last week and we were
 allowed to choose our testing frameworks. Kirk Haines and I were
 paired up and we cracked open the code for a few test
 frameworks...

 I MUST say that minitest is *very* readable / understandable
 compared to the 'other two' options we looked at. Nicely done and
 thank you for helping us keep our mental sanity."

-- Wayne E. Seguin

minitest/test is a small and incredibly fast unit testing framework. It provides a rich set of assertions to make your tests clean and readable.

minitest/spec is a functionally complete spec engine. It hooks onto minitest/test and seamlessly bridges test assertions over to spec expectations.

minitest/benchmark is an awesome way to assert the performance of your algorithms in a repeatable manner. Now you can assert that your newb co-worker doesn't replace your linear algorithm with an exponential one!

minitest/pride shows pride in testing and adds coloring to your test output. I guess it is an example of how to write IO pipes too. :P

minitest/test is meant to have a clean implementation for language implementors that need a minimal set of methods to bootstrap a working test suite. For example, there is no magic involved for test-case discovery.

"Again, I can't praise enough the idea of a testing/specing
 framework that I can actually read in full in one sitting!"

-- Piotr Szotkowski

Comparing to rspec:

rspec is a testing DSL. minitest is ruby.

-- Adam Hawkins, "Bow Before MiniTest"

minitest doesn't reinvent anything that ruby already provides, like: classes, modules, inheritance, methods. This means you only have to learn ruby to use minitest and all of your regular OO practices like extract-method refactorings still apply.

== FEATURES/PROBLEMS:

  • minitest/autorun - the easy and explicit way to run all your tests.
  • minitest/test - a very fast, simple, and clean test system.
  • minitest/spec - a very fast, simple, and clean spec system.
  • minitest/benchmark - an awesome way to assert your algorithm's performance.
  • minitest/pride - show your pride in testing!
  • minitest/test_task - a full-featured and clean rake task generator.
  • Incredibly small and fast runner, but no bells and whistles.
  • Written by squishy human beings. Software can never be perfect. We will all eventually die.

== RATIONALE:

See design_rationale.rb to see how specs and tests work in minitest.

== SYNOPSIS:

Given that you'd like to test the following class:

class Meme def i_can_has_cheezburger? "OHAI!" end

def will_it_blend?
  "YES!"
end

end

=== Unit tests

Define your tests as methods beginning with +test_+. Use {assertions}[/minitest/Minitest/Assertions.html] to test for results or state.

require "minitest/autorun"

class TestMeme < Minitest::Test def setup @meme = Meme.new end

def test_that_kitty_can_eat
  assert_equal "OHAI!", @meme.i_can_has_cheezburger?
end

def test_that_it_will_not_blend
  refute_match /^no/i, @meme.will_it_blend?
end

def test_that_will_be_skipped
  skip "test this later"
end

end

=== Specs

Use {expectations}[/minitest/Minitest/Expectations.html] to check results or state. They must be wrapped in a value call (eg +_+).

require "minitest/autorun"

describe Meme do before do @meme = Meme.new end

describe "when asked about cheeseburgers" do
  it "must respond positively" do
    _(@meme.i_can_has_cheezburger?).must_equal "OHAI!"
  end
end

describe "when asked about blending possibilities" do
  it "won't say no" do
    _(@meme.will_it_blend?).wont_match /^no/i
  end
end

end

For matchers support check out:

  • https://github.com/wojtekmach/minitest-matchers
  • https://github.com/rmm5t/minitest-matchers_vaccine

=== Benchmarks

Add {benchmarks}[/minitest/Minitest/Benchmark.html] to your tests.

optionally run benchmarks, good for CI-only work!

require "minitest/benchmark" if ENV["BENCH"]

class TestMeme < Minitest::Benchmark # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000] def bench_my_algorithm assert_performance_linear 0.9999 do |n| # n is a range value @obj.my_algorithm(n) end end end

Or add them to your specs. If you make benchmarks optional, you'll need to wrap your benchmarks in a conditional since the methods won't be defined. In minitest 5, the describe name needs to match <tt>/Bench(mark)?$/</tt>.

describe "Meme Benchmark" do if ENV["BENCH"] then bench_performance_linear "my_algorithm", 0.9999 do |n| 100.times do @obj.my_algorithm(n) end end end end

outputs something like:

Running benchmarks:

TestBlah 100 1000 10000 bench_my_algorithm 0.006167 0.079279 0.786993 bench_other_algorithm 0.061679 0.792797 7.869932

Output is tab-delimited to make it easy to paste into a spreadsheet.

=== Running Your Tests

Ideally, you'll use a rake task to run your tests (see below), either piecemeal or all at once. BUT! You don't have to:

% ruby -Ilib:test test/minitest/test_minitest_test.rb
Run options: --seed 37685

# Running:

...................................................................... (etc)

Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s.

155 runs, 317 assertions, 0 failures, 0 errors, 0 skips

There are runtime options available, both from minitest itself, and also provided via plugins. To see them, simply run with +--help+:

% ruby -Ilib:test test/minitest/test_minitest_test.rb --help
minitest options:
    -h, --help                       Display this help.
    -s, --seed SEED                  Sets random seed. Also via env. Eg: SEED=n rake
    -v, --verbose                    Verbose. Show progress processing files.
    -n, --name PATTERN               Filter run on /regexp/ or string.
    -e, --exclude PATTERN            Exclude /regexp/ or string from run.

Known extensions: pride, autotest
    -p, --pride                      Pride. Show your testing pride!
    -a, --autotest                   Connect to autotest server.

=== Rake Tasks

You can set up a rake task to run all your tests by adding this to your Rakefile:

require "minitest/test_task"

Minitest::TestTask.create # named test, sensible defaults

# or more explicitly:

Minitest::TestTask.create(:test) do |t|
  t.libs << "test"
  t.libs << "lib"
  t.warning = false
  t.test_globs = ["test/**/*_test.rb"]
end

task :default => :test

Each of these will generate 4 tasks:

rake test          :: Run the test suite.
rake test:cmd      :: Print out the test command.
rake test:isolated :: Show which test files fail when run separately.
rake test:slow     :: Show bottom 25 tests sorted by time.

=== Rake Task Variables

There are a bunch of variables you can supply to rake to modify the run.

MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
N             :: -n: Tests to run (string or /regexp/).
X             :: -x: Tests to exclude (string or /regexp/).
A             :: Any extra arguments. Honors shell quoting.
MT_CPU        :: How many threads to use for parallel test runs
SEED          :: -s --seed Sets random seed.
TESTOPTS      :: Deprecated, same as A
FILTER        :: Deprecated, same as A

== Writing Extensions

To define a plugin, add a file named minitest/XXX_plugin.rb to your project/gem. That file must be discoverable via ruby's LOAD_PATH (via rubygems or otherwise). Minitest will find and require that file using Gem.find_files. It will then try to call +plugin_XXX_init+ during startup. The option processor will also try to call +plugin_XXX_options+ passing the OptionParser instance and the current options hash. This lets you register your own command-line options. Here's a totally bogus example:

# minitest/bogus_plugin.rb:

module Minitest
  def self.plugin_bogus_options(opts, options)
    opts.on "--myci", "Report results to my CI" do
      options[:myci] = true
      options[:myci_addr] = get_myci_addr
      options[:myci_port] = get_myci_port
    end
  end

  def self.plugin_bogus_init(options)
    self.reporter << MyCI.new(options) if options[:myci]
  end
end

=== Adding custom reporters

Minitest uses composite reporter to output test results using multiple reporter instances. You can add new reporters to the composite during the init_plugins phase. As we saw in +plugin_bogus_init+ above, you simply add your reporter instance to the composite via <tt><<</tt>.

+AbstractReporter+ defines the API for reporters. You may subclass it and override any method you want to achieve your desired behavior.

start :: Called when the run has started. record :: Called for each result, passed or otherwise. report :: Called at the end of the run. passed? :: Called to see if you detected any problems.

Using our example above, here is how we might implement MyCI:

# minitest/bogus_plugin.rb

module Minitest
  class MyCI < AbstractReporter
    attr_accessor :results, :addr, :port

    def initialize options
      self.results = []
      self.addr = options[:myci_addr]
      self.port = options[:myci_port]
    end

    def record result
      self.
View on GitHub
GitHub Stars3.4k
CategoryDevelopment
Updated1d ago
Forks582

Languages

Ruby

Security Score

85/100

Audited on Mar 30, 2026

No findings