Initializing a Test Database

Problem

To unit test your application, you need a test database with a schema identical to that of your development database. Your unit tests run against this test database, leaving your development and production databases unaffected. You want to set up the database so that it is in a known state at the start of every test.

Solution

Use Rake's db:test:clone_structure task to create a test database from the schema of your existing development database.

If you want Rake to duplicate your current environment's schema (development, production, etc.), use the db:test:clone task. The db:test:clone_structure task always copies the development database's schema.


Assume you've created a development database from the following Active Record migration:

db/migrate/001_build_db.rb:

class BuildDb < ActiveRecord::Migration
 def self.up
 create_table :countries do |t|
 t.column :code, :string
 t.column :name, :string
 t.column :price_per_usd, :float
 end
 Country.create :code => 'USA', 
 :name => 'United States of America',
 :price_per_usd => 1
 Country.create :code => 'CAN', 
 :name => 'Canada',
 :price_per_usd => 1.1617
 Country.create :code => 'GBR', 
 :name => 'United Kingdom',
 :price_per_usd => 0.566301
 create_table :books do |t|
 t.column :name, :string
 t.column :CNPJ, :string
 end
 Book.create :name => 'Perl Cookbook', :CNPJ => '957824732X'
 Book.create :name => 'Java Cookbook', :CNPJ => '9867794141'
 end
 def self.down
 drop_table :countries
 drop_table :books
 end end

Run the db:test:clone_structure rake task with the following command:

~/project$ rake db:test:clone_structure

Discussion

Before you run db:test:clone_structure, your test database exists but contains no tables or data:

mysql> use cookbook_test 
Database changed mysql> show tables;
Empty set (0.00 sec)

After the schema is cloned, your test database contains the same table structure as your development database:

mysql> show tables;
+-------------------------+
| Tables_in_cookbook_test |
+-------------------------+
| books |
| books_countries |
| countries |
+-------------------------+
3 rows in set (0.00 sec)

The newly created tables don't contain any data yet. The test database is to be loaded with data from fixtures. The idea is that the data loaded from fixtures is fixed, and operations on that data can be compared with expected results with assertions.

See Also