From: John Feminella on
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