RSpec's been on my list of tools
to adopt for a while now. My current project is unlikely to migrate from
Test::Unit,
and there's no plan for me to migrate off that project, so I decided to switch
Nestegg over to use it. It's not
the sort of hard-core dive-in that's going to force me to get fluent, but it's
a nice first baby step. (I'm mean really baby: the whole gem is only
one module.)
Here's what the migration looked like.
I started by running
newgem -t rspec fakegem
to get a template for my spec directory and Rakefile, then pulled the
spec-related stuff that generated into nestegg.
The spec folder had
- spec_helper.rb, which just does
require 'spec',
- spec.opts, which just hash
--colour, and
- fakegem_spec.rb, which is a do-nothing spec.
The Rakefile had this up top
begin
require 'spec/rake/spectask'
rescue LoadError
puts 'To use rspec for testing you must install rspec gem:'
puts '$ sudo gem install rspec'
exit
end
and this down below
desc "Run the specs under spec"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "spec/spec.opts"]
t.spec_files = FileList['spec/**/*_spec.rb']
end
desc "Default task is to run specs"
task :default => :spec
After a sudo gem install rspec, I was up and running. The
default rake target ran my Test::Unit suite, then the do-nothing spec.
Sweet.
I moved the do-nothing spec to nestegg/nesting_exception_spec.rb and copied
each of my test names over (which was especially effortless since
my Test::Unit suite was using
RSpec-ish
test declarations). I also remembered reading that you could pass a class to
the describe method, so I landed with this
describe Nestegg::NestingException do
it "includes cause in backtrace" do
violated "Be sure to write your specs"
end
it "includes cause's backtrace after cause in backtrace" do
violated "Be sure to write your specs"
end
it "removes duplicated backtrace elements from nesting exception" do
violated "Be sure to write your specs"
end
it "defaults cause to current raised exception ($!)" do
violated "Be sure to write your specs"
end
end
Then I started at the top and copied the body of the first test into the
spec. I'd anticipated some pain related to the helper methods that lived in
my test, but those turned out to be completely portable. The only thing I had
to modify in each test was the assertion. With special thanks to the very helpful
Test::Unit
Cheat Sheet, here are the before-and-afters.
-
assert_true e.backtrace.include?("cause: StandardError: #{cause.message}")
became
e.backtrace.should include("cause: StandardError: #{cause.message}")
-
assert_equal ["cause: StandardError: #{cause.message}", "line_one", "line_two"], e.backtrace[-3..-1]
became
e.backtrace[-3..-1].should == ["cause: StandardError: #{cause.message}", "line_one", "line_two"]
-
assert_match(/#{__FILE__}:\d+:in `test_.+'$/, e.backtrace[0])
assert_equal "cause: StandardError: msg", e.backtrace[1]
became
e.backtrace[0..1].should == ["#{__FILE__}:#{line}", "cause: StandardError: msg"]
Note that on that one I'd done a Regexp match in the Test::Unit version, because I didn't want
to put the test method name in the content of the test. Since RSpec apparently
doesn't create methods out of examples, the backtrace line I'm interested in is
free of any method name. To enable a simple equality check, I saved
the line number on which the exception was raised in a temporary variable.
-
assert_equal expected_cause, raised_error.cause
became
raised_error.cause.should == expected_cause
See here
for the whole shebang. The original
test is here. The two files are incredibly similar, no?
Just like that, Nestegg was converted. I was a little sad I hadn't used
mocha, since that could have meant switching
to RSpec's mocking
library. Oh well. That'll give me something to look forward to when I
migrate Handoff.