Preparing your test database: mind the differences

Instead of running all missing migrations on your test database with rake db:migrate RAILS_ENV=test you can also use a handful of rake tasks to prepare the database structure directly. They can produce different results, though.

In a nutshell, to ensure your test database gains the correct structure:

  • Don't use rake db:test:prepare carelessly
  • or use rake db:test:clone_structure ← preferred :)
  • or use rake db:migrate RAILS_ENV=test and don't mix it with other ways, like some of the rake tasks.

rake db:test:prepare

Be default, this loads you schema.rb into the test database. You may need to run a rake db:schema:dump before to get an updated schema.rb -- else you might load an outdated database structure.

Since the schema.rb does not hold any SQL specific information, like charsets or collations, your test database may differ from your development database in such aspects (because they will be defined by the database defaults when tables are created without further information).

To avoid this problem, your environment.rb needs to say:

config.active_record.schema_format = :sql

This will make a db/development_structure.sql appear which is then also read and loaded when you do a db:test:prepare.

rake db:test:clone

You don't need to dump your database schema explicitly when calling this rake task (it generates the schema.rb for you) -- but you may run into problems. The task's description reads:

rake db:test:clone # Recreate the test database from the current environment's database schema

This is exactly what happens. Even if your environment.rb defines a different schema_format (like above) it will not be used but instead the test database's structure is read from the schema.rb file.

Using rake db:test:clone will then again result in a different structure if you have any tables or columns whose charset or collation differ from the database default.

rake db:test:clone_structure

Using this command will save you the above hassle. Though it is pretty cumbersome to type, it's doing what you want:

rake db:test:clone_structure # Recreate the test databases from the development structure

That will make your test database have the same structure, including charsets and collations, like your development database.

Arne Hartherz Over 12 years ago