Short note on a repeatable starting point for TDD

For testing to be useful, it needs to be repeatable.  Curious, here’s some notes I took when investigating what happens when you run ‘rake spec’.  This also would apply similarly for cucumber.
Rspec:
rspec specs can be run in various ways:
$ rake spec
$  spec spec
$ spec spec/controller/somefile_spec.rb
$  spec spec/controller/somefile_spec.rb:31  # specify a line number
$ autospec    # ( see  http://zentest.rubyforge.org/ZenTest/ for docs or even better, check  the source. )
Only the first command sets up the environment from scratch.  The other methods assume a working environment and if your tests assume a working environment and that assumption is invalid, then boom!

What happens in a rake spec?  Here’s what I see when I run it (edited for brevity and comments added)

$ rake --trace spec | grep Execute                #  ignore the Invoke lines.  we're only interested in what actually gets  run
(in /Users/eddykim/work/coupa_gitrepo)
** Execute environment
** Execute db:abort_if_pending_migrations
** Execute  db:test:prepare
** Execute db:test:purge        #-- drops all the  tables in the db
** Execute db:test:load          #-- creates the  tables, using schema.rb  (does not populate the tables with any data)
**  Execute db:schema:load     #-- is this really necessary for the test  db?
** Execute spec

The following is the bare minimum of things that need to be setup a clean and working database before you start your TDD mojo.

$ rake db:test:purge
$ rake  db:test:load
$ RAILS_ENV=test rake db:seed:load SEEDS='all'     # (This is a custom task in our project)
Notice that I skip running the db:schema:load which seems to be an unnecessary, time sucking task.  At which point you can run spec manually, or autospec if you so desire.
Additionally, the db:seeds:load task has a similar function as running rake db:fixtures:load.
Moral of the story:  Make sure your test database is in a known good starting state before running your tests.  But to keep your testing speed up, you don’t need to re-setup the db on every test run if you are using transactions to keep your test db clean.

Leave a Reply