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
- spec.opts, which just hash
- fakegem_spec.rb, which is a do-nothing spec.
The Rakefile had this up top
begin 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
sudo gem install rspec, I was up and running. The
default rake target ran my Test::Unit suite, then the do-nothing spec.
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
test declarations). I also remembered reading that you could pass a class to
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.
e.backtrace.should include("cause: StandardError: ")
e.backtrace[-3..-1].should == ["cause: StandardError: ", "line_one", "line_two"]
e.backtrace[0..1].should == [":", "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.
raised_error.cause.should == expected_cause
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.