I’m of the (perhaps misguided) opinion that since Rake tasks are Ruby
code, they need to be tested. However, I’ve never done this before,
but thought it was worth looking into. So I wrote a simple RSpec test:
[[[[ ./test/spec.rb
describe “Rake tasks” do
require ‘rake’
before(:each) do
@rake = Rake::Application.new
# @rake.init # Uncomment and this test
will blow up.
# @rake.load_rakefile() # Uncomment and this test will blowup.
Rake.application = @rake
end
after(:each) do
Rake.application = nil
end
it "should have at least one RSpec test to execute" do
Rake.application["specs"].spec_files.size.should > 0
end
end
]]]]
There is a task called “specs” in my ./Rakefile.rb, which is a
Spec::Rake::SpecTask that just runs any file matching spec/**/*.rb. If
I inspect the Rake::Application instance I get when normally running
(with --trace), I get this:
#<Rake::Application:0x9c33154 @tasks={“specs”=><Rake::Task specs =>
[]>}, @rules=[], @scope=[], @last_description=nil, @name=“rake”,
@rakefiles=[“rakefile”, “Rakefile”, “rakefile.rb”, “Rakefile.rb”],
@rakefile=“Rakefile.rb”, @pending_imports=[], @imported=[],
@loaders={".rb"=>#Rake::DefaultLoader:0x9c32e28,
“.rf”=>#Rake::DefaultLoader:0x9c32d9c,
“.rake”=>#Rake::DefaultLoader:0x9c32d10},
@default_loader=#Rake::DefaultLoader:0x9c32ed0,
@original_dir="/home/johnf/dev/playground",
@top_level_tasks=[“tests:specs”], @tty_output=true,
@options=#<OpenStruct rakelib=[“rakelib”], trace=true>>
Notice the presence of @rakefile=“Rakefile.rb” and that the @tasks
hash is populated. (You can also see trace=true
in the @options
OpenStruct.) However, if I inspect the Rake::Application instance that
I create inside test/spec.rb, it’s a lot sparser; in particular,
there’s no Rakefile loaded. Understandably, the spec test then fails,
saying that the Rake::Application instance doesn’t know how to run a
task called “specs”.
No problem; the documentation says you need to call #init
on new
Application instances to get them primed. When I do that, however, the
Rake::Application instance inside the spec test exits abruptly, the
spec task fails, and the outer Rake instance complains “rake
aborted!”. The stacktrace ends at the spec-test level, presumably
because --trace isn’t turned on for the inner Rake::Application
instance. I also tried calling #load_rakefile() instead, but with
similarly unpromising results.
I’m a little stumped at this point, and am unable to divine anything
further from the documentation. What’s the right way to write this
spec?
~ jf