$ 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

$ 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