I'm a fair开发者_开发问答ly novice tester, but have been trying to get better at TDD in Rails.
RSpec works great, but my tests are pretty slow. I've heard that MiniTest is a lot faster, and the MiniTest/Spec DSL looks pretty similar to how I'm used to working with RSpec, so I thought I'd give it a try.
However, I have not been able to find anything on the web that provides a walkthrough of how to setup and run Minitest. I learned how to test from the RSpec book, and I have no idea how Test::Unit or MiniTest are supposed to work. I have the gem in my gemfile, I've written a few simple tests, but I have no idea where to put them or how to run them. I figure this is one of those things that's so obvious nobody has bothered to write it down...
Can anyone explain to me how to setup some some Minitest/spec files and get them running so I can compare the performance against Rspec?
EDIT
Specifically these are the basics I most need to know:
- Do you need a test_helper file (like spec_helper) and if so how do you create it?
- How do you run minitest? There doesn't seem to be an equivalent to
rspec spec
orrspec path/to/file_spec.rb
, what am I missing?
Thanks!
This question is similar to How to run all tests with minitest?
Using Ruby 1.9.3 and Rake 0.9.2.2, given a directory layout like this:
Rakefile
lib/alpha.rb
spec/alpha_spec.rb
Here is what alpha_spec.rb
might look like:
require 'minitest/spec'
require 'minitest/autorun' # arranges for minitest to run (in an exit handler, so it runs last)
require 'alpha'
describe 'Alpha' do
it 'greets you by name' do
Alpha.new.greet('Alice').must_equal('hello, Alice')
end
end
And here's Rakefile
require 'rake'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.pattern = 'spec/**/*_spec.rb'
end
You can run
- all tests:
rake test
- one test:
ruby -Ilib spec/alpha_spec.rb
I don't know if using a spec_helper.rb
with minitest is common or not. There does not appear to be a convenience method for loading one. Add this to the Rakefile:
require 'rake'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.pattern = 'spec/**/*_spec.rb'
t.libs.push 'spec'
end
Then spec/spec_helper.rb
can contain various redundant things:
require 'minitest/spec'
require 'minitest/autorun'
require 'alpha'
And spec/alpha_spec.rb
replaces the redundant parts with:
require 'spec_helper'
- all tests:
rake test
- one test:
ruby -Ilib -Ispec spec/alpha_spec.rb
Note that watchr or spork are not requirements for running tests. They're a convenience for doing autotesting. But the most basic way you can run a set of MiniTest tests is with ruby itself:
$ ruby myfileoftests.rb
What version of Ruby are you using?
In my understanding, 1.9 introduced MiniTest
, which replaces Test::Unit
entirely, with a backwards compatible API. So if you're on 1.9 and your Rails app references Test::Unit
, it's actually already using MiniTest
.
Take a look at your Ruby source - test/unit.rb
for 1.9.2 has the following requires:
require 'minitest/unit'
require 'test/unit/assertions'
require 'test/unit/testcase'
And test/unit/assertions
includes MiniTest::Assertions
.
Getting your tests to run faster is a whole other dark art. Take a look at spork and watchr. The former keeps your app initialized, reloads modified files, and forks before each run of your test suite. The latter watches files in your repo for changes, and automatically runs their associated test cases.
Together they give you a pretty mean TDD setup. You write a test case for your new model, and it automatically runs and fails. Then whenever you save the associated model, that testcase re-runs, very quickly. You get near instant feedback on whether you're red/green.
They're both a little tricky to get set up and behaving nicely together, so check back with some more questions if you get stuck.
Best of luck!
Check out this getting started video for minitest-rails. It walks through the process for setting up Minitest for a Rails app.
http://www.youtube.com/watch?v=xA2f2zBNvsc
The walkthrough shows how to create a helper file as well as how to run the tests using a rake task. If you want to run a specific test you can do so with the following:
ruby -Itest test/models/user_test.rb
Newer versions of RSpec (since 2.8 released in Jan 2012) have a dramatic speed increase. Here is an exploration of performance differences and a comparison with MiniTest.
Also, I found this screencast by Ryan Bates an excellent introduction to MiniTest. Note that this is one of the pro videos and you will need to subscribe to watch it.
Here is my entire rakefile
, which I put in my top directory:
task :default => :test
task :test do
Dir.glob('./test/*_test.rb').each { |file| require file}
end
To run all my Minitest files at once, I just type rake
. That's it!
Make sure to have require 'minitest/autorun'
at the top of each of your Minitest files. Dir.glob definitely DOES work with Minitest.
To get pretty, colored Minitest output, with names of all my test methods, I have the file minitest_helper.rb
in my /test directory. (Had to install the gem minitest-reporters):
require 'minitest/reporters'
Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
require 'minitest/autorun'
I just had to require_relative './minitest_helper'
at the top of each of my test files.
Patrick wrote a really good explanation and example. For future readers just be aware that global expectations are now depreciated, and will be removed in Minitest 6. It requires an almost trivial change in wrapping the thing you are testing in a call to expect
.
require 'minitest/spec'
require 'minitest/autorun' # arranges for minitest to run (in an exit handler, so it runs last)
require 'alpha'
describe 'Alpha' do
it 'greets you by name' do
expect(Alpha.new.greet('Alice')).must_equal('hello, Alice')
end
end
精彩评论