Recipe 7.3. Importing Test Data with CSV Fixtures


Problem

You want to import data into your test database from another data source. Perhaps that source is an comma-separated values (CSV) file from a spreadsheet program or even a database. You could use YAML fixtures, but with large datasets, that would be tedious.

Solution

Use CSV fixtures to create test data from the output of another program or database.

Assume you have a database with a single countries table. The following migration sets up this table:

db/migrate/001_create_countries.rb:

class CreateCountries < ActiveRecord::Migration   def self.up     create_table :countries do |t|        t.column :country_id, :string       t.column :name, :string     end    end    def self.down     drop_table :countries   end  end

If your test database is empty, initialize it with the schema from your development database:

$ rake db:test:clone_structure             

Now create a country model using the Rails model generator:

$ ruby script/generate model country       exists  app/models/       exists  test/unit/       exists  test/fixtures/       create  app/models/country.rb       create  test/unit/country_test.rb       create  test/fixtures/countries.yml

Create a CSV file containing a list of countries. The first line contains the field names in the table that the rest of the data corresponds to. Here are the first 10 lines of countries.csv:

test/fixtures/countries.csv:

country_id,name ABW,Aruba AFG,Afghanistan AGO,Angola AIA,Anguilla ALB,Albania AND,Andorra ANT,Netherlands Antilles ARE,United Arab Emirates ARG,Argentina

As with YAML fixtures, CSV fixtures are loaded into the test environment using Test::Unit's fixtures method. The symbol form of the fixture's filename, excluding the extension, is passed to fixtures.

test/unit/country_test.rb:

require File.dirname(__FILE__) + '/../test_helper' class CountryTest < Test::Unit::TestCase   fixtures :countries   def test_country_fixtures     countries = Country.find(:all)     assert_equal 230, countries.length   end end

Discussion

Running the test shows that the fixtures were loaded successfully. The assertionthat there are 230 country recordsis also successful.

$ ruby test/unit/country_test.rb  Loaded suite test/unit/country_test Started . Finished in 0.813545 seconds. 1 tests, 1 assertions, 0 failures, 0 errors

YAML fixtures are more readable and easier to update by hand than CSV files, but CSV fixtures are valuable since a number of programs support CSV exports. For example, using a CSV import would be helpful to reproduce a bug that's occurring only in your production environment. To reproduce the bug, export a snapshot of the tables on your production server to CSV files.

These files can be put in a temporary directory where they won't interfere with any existing fixtures. The syntax for specifying fixtures in a subdirectory of the standard fixtures directory is a bit different. Call the create_fixtures method of the Fixtures class, which takes the directory and table name as arguments. Here's the test class again, loading the countries fixtures file from the live_data subdirectory:

require File.dirname(__FILE__) + '/../test_helper' class CountryTest < Test::Unit::TestCase   Fixtures.create_fixtures(File.dirname(__FILE__) +                            '/../fixtures/live_data',                            :countries)   def test_truth     countries = Country.find(:all)     assert_equal 230, countries.length   end end

See Also

  • Section 7.4"




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net