Recipe 7.8. Loading Test Data with YAML Fixtures


Problem

It's important that your test database contains known data that is common to each test case for the model being tested. You don't want your tests to pass or fail depending on what's in the database when they run; that defeats the whole purpose of testing. You have created data to test the boundary conditions of your application, and you want an efficient way to load that data into your database without using SQL.

Solution

Use YAML to create a file containing test fixtures to be loaded into your test database.

Your database contains a single books table as created by the following migration:

db/migrate/001_build_db.rb:

class BuildDb < ActiveRecord::Migration   def self.up     create_table :books do |t|       t.column :title, :string       t.column :isbn, :string       t.column :ean, :string       t.column :upc, :string       t.column :edition, :string     end   end   def self.down     drop_table :books   end end

Create a Book model using the Rails generate script (notice the test scaffolding that's created by this command):

$ ruby script/generate model book       exists  app/models/       exists  test/unit/       exists  test/fixtures/       create  app/models/book.rb       create  test/unit/book_test.rb       create  test/fixtures/books.yml

Now, create a fixture containing your test data in the books.yml file under the test/fixtures directory:

test/fixtures/books.yml:

perl_cookbook:       id: 1       title: Perl Cookbook     isbn: 957824732X      ean: 9789578247321      upc: 636920527114  edition: 1   java_cookbook:       id: 2       title: Java Cookbook     isbn: 9867794141      ean: 9789867794147      upc: 236920522114  edition: 1 mysql_cookbook:       id: 3       title: MySQL Cookbook     isbn: 059652708X      ean: 9780596527082      upc: 636920527084  edition: 2

Fixtures are loaded by the Test::Unit module by passing the name of the fixture file, without the extension, as a symbol to the fixtures method. The following unit test class shows the books fixtures being loaded with a test confirming success:

test/unit/book_test.rb:

require File.dirname(__FILE__) + '/../test_helper' class BookTest < Test::Unit::TestCase   fixtures :books   def test_fixtures_loaded     perl_book = books(:perl_cookbook)     assert_kind_of Book, perl_book   end end

Discussion

YAML is a data serialization format designed to be easily readable and writable by humans, as well as by scripting languages such as Python and Ruby. YAML is often used for data serialization and configuration settings, where it serves as a more transparent alternative to XML or a custom configuration language.

Before it runs each test case, the Test::Unit module uses the solution's fixture file (books.yml) to initialize the books table of the test database. In other words, each test case starts with a fresh copy of the test data, just as it appears in the YAML fixture. This way, tests can be isolated with no danger of side effects.

The test_fixtures_loaded test case of the BookTest class tests that the book fixtures are loaded successfully and that an Active Record Book object is created. Individual records in a YAML fixture are labeled for convenient reference. You can use the books fixture accessor method to return book objects by passing it one of the fixture labels. In the solution, we return an object representing the Perl Cookbook by calling books(:perl_cookbook). The assertion tests that this object is, in fact, an instance of the Book class. The following output shows the successful results of running the test:

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

See Also

  • Section 7.3"

  • 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