MiniTest is the preferred method of testing in Ruby 1.9.3 and up. Ruby is currently at version 2.1.2, so if you haven’t taken a look at MiniTest just yet, I recommend checking it out. There are some compelling features of MiniTest that make it a viable option as a testing library:
MiniTest supports assertions and test cases just like its predecessor Test::Unit. If an existing test suite is written in Test::Unit, conversion is relatively easy and painless.
In addition to the assert syntax, MiniTest supports an expectation syntax similar to RSpec. The expectation syntax is largely a preference for each individual developer (or team), and there is no need to pull in an external library.
MiniTest supports performance benchmarking out of the box. As the documentation states, “you can assert that your newb co-worker doesn’t replace your linear algorithm with an exponential one!”
Mocking and Stubbing
Mocking and stubbing are built-in to MiniTest! There’s no need to add in any separate libraries.
Writing Your First Test
In this section, we’re going to write a simple class and a test for it. This will give us an idea of how MiniTest works.
Let’s take a look at following simple class (
class Blog def title "Treehouse Blog" end end
Writing a test for it is simple using MiniTest. Here’s
require 'minitest/autorun' require './blog' class TestBlog < Minitest::Test def setup @blog = Blog.new end def test_title_is_treehouse assert_equal "Treehouse Blog", @blog.title end end
We run it the following way:
And you should see:
$ ruby blog_test.rb Run options: --seed 30102 # Running: . Finished in 0.000980s, 1020.4082 runs/s, 1020.4082 assertions/s. 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
Writing Your First Expectation
MiniTest also supports the option of writing tests in the expectation style. If you’ve used RSpec, the syntax is similar and you’ll feel right at home with
it blocks. Here’s what the same test would look like when writing as an expectation (
require 'minitest/autorun' require './blog' describe Blog do before do @blog = Blog.new end describe "#title" do it "returns the title of the blog" do @blog.title.must_equal "Treehouse Blog" end end end
Run it the same way:
$ ruby blog_spec.rb Run options: --seed 19668 # Running: . Finished in 0.001998s, 500.5005 runs/s, 500.5005 assertions/s. 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
Supported Assertions and Expectations
There are a ton of different assertions that are supported in Minitest. Some of the assertions that you’ll be using most often are:
MiniTest and Rails
Using MiniTest with Rails is completely supported. It takes a slight bit of setup to get working, however, it is just as easy as using something like RSpec. There are a couple of different options when using
MiniTest with a Rails application. The first one we’ll take a look at is minitest-rails. Setup is straightforward in this library. To install, open up your
Gemfile and place the following:
Then install it:
bundle install rails generate minitest:install
It’s also possible specify using the expectation format by default in
config.generators do |g| g.test_framework :minitest, spec: true end
Your application will now have minitest files generated by default when you run the
rails generate command. Easy!
Another library worth looking at is minitest-spec-rails. This library accomplishes the same thing as the
minitest-rails gem. However, minitest-spec-rails has slightly different priorities which you can read about in the Readme. Either library works, and I encourage you to read both project’s documentation and decide which may be a better fit for your project.
There are a wealth of testing options in the Ruby community. For a while, it seemed like a new testing library popped up every day. If you’re going to be doing Ruby development, it is important to be familiar with the standard testing library that ships with the language. If you haven’t given
MiniTest a try, check it out! You just may like what you see.
Update: Ryan Davis has pointed out that in MiniTest 4, tests should inherit from
MiniTest::Unit::TestCase and in MiniTest 5, tests should inherit from
Minitest::Test. The code in the article has been updated to reflect this. Thanks, Ryan!