$ rake spec
(in /Users/sarah/src/../my_app)
You have 1 pending migrations:
20110416135407 CreateCourses

The rake spec command reminds us that we need to run our migration before running
our tests. In fact, it does a whole lot more than that. There are a whole bunch of best practices rolled in that one
command. To see exactly what is going on, we can run rake spec with the –trace
option:


$ rake spec --trace
(in /Users/sarah/src/tfr/svn/Book/code/class_app_new_source)
** Invoke spec (first_time)
** Invoke db:test:prepare (first_time)
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:abort_if_pending_migrations
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment
** Execute db:test:purge
** Execute db:test:load
** Invoke db:schema:load (first_time)
** Invoke environment
** Execute db:schema:load
** Execute spec

When it says invoke it is calling a particular rake task, but then it will call its dependencies. To really see what is happening in what order, check out the execute commands. The commands db:test:prepare and db:test:load don’t do much themselves, aside from setting up the environment and executing another task or two. We can see from the output that rake is actually executing the following steps:

  1. Don’t run the specs if there are pending migrations in the development database. (db:abort_if_pending_migrations)

  2. Drop the test database (db:test:purge)

  3. Load the schema into the test database (db:schema:load in environment “test”)

These steps make sure that we are always testing in a clean environment, so we know exactly what we’re testing when we run our specs.

The code that makes this happen in Rails 3, can now be found in railties. (Thanks to @pixeltrix for pointing me to it.)/62206174505873408

One thought on “what exactly does rake spec do?

  1. I include Rake.application.options.trace = true in my Rakefiles so that I always see not only the tasks that are executed, but also the backtrace when there’s an error (why would anyone not want to see this??).

    And yes, tracing rake spec like this shows some interesting things – in particular, why the task is so slow. That’s why most of the time, I run a command like

    bundle exec rspec -b spec/models/model_spec.rb:204

    -b is for backtrace, and, again, I have to wonder why this is not the default? When you get a runtime error, why would you ever not want to see what caused it?

What do you think?