Christoph Schiessl's Blog

A Quick Check for Pending Migrations Before Running your Test Suite

As Rails developers, we are constantly switching between writing application code & tests and running our tests. While this is a great workflow, it sometimes leads to problems. Namely, if we change our database schema, but forget to migrate the DB before re-running the test suite.

You don’t need me to tell you, that your test suite is basically worthless if your schema isn’t up-to-date. You simply can’t rely on its results. Suppose you did forget to migrate your database, but all your tests are green nonetheless. That’s the worst situation I can think of, because you would conclude that your project is healthy, even though, in reality, it could be fatally broken.

That being said, it would be easy enough to migrate your development and test databases with a single command – you just have to remember to do it:

1
$ rake db:migrate db:test:prepare

The following code is intended to be a safe-guard, ensuring that your test suite fails quickly if there are pending migrations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Raise an error and abort the test-run
#   there are any pending migrations:
if defined?(ActiveRecord::Migrator)
  migrator = ActiveRecord::Migrator.new(
    :up, ActiveRecord::Migrator.migrations_paths
  )

  if (pending = migrator.pending_migrations).any?
    raise %Q[
      Attention! The following migrations are PENDING:
      #{pending.map(&:filename).join("\n")}
      Please run 'rake db:migrate db:test:prepare'...
    ]
  end
end

This snippet works with Rails >= 3.0 and all test frameworks. For instance, if you are using rspec, just copy the snippet into your spec_helper.rb file and you should be good.


Notes
Software: Ruby on Rails >= 3.0 (with ActiveRecord)