CSC/ECE 517 Fall 2012/ch2a 2w33 pv
SaaS - 5.5 - Fixtures and Factories 
One of the best parts about Ruby community is the degree to which the developers focus on testing. Developers work with 3 types of tests namely, units (for models), functional  (for controllers) and integration  tests. Testing requires providing the code with inputs and matching the output generated with the expected outputs. Testing data from the database is however is a little challenging since data should be first stored in the database so that the tests can run on it. These tests may make a few modifications(adding, deleting or updating rows) to the data present in the database. These changes will stay for the next test which is not desirable. Therefore, we need a way to put the database into a known state before the next test begins. This can be achieved using Fixtures and Factories.
Fixtures are sample data on which all the tests run.
There can be 3 types of fixtures:
1. YAML fixtures
2. CSV fixtures
3. Single-file fixtures
YAML is a recursive acronym for "YAML Ain't Markup Language". YAML is a file format which describes data structures in a non-verbose, human-readable format. YAML consists of name-value pairs within a hierarchy, and indentation indicates where in the hierarchy a particular name-value pair exists. This file ends with .yml extension.
The following example shows the format of a YAML fixture for a post:
post_one: title: one description: post_one_desc category: category_one post_two: title: two description: post_two_desc category: category_two
Comma Separated Value format can be used to store sample data. The files end with ".csv" extension. The first line of the CSV file is a comma-separated list of field names. The rest of the file contains the actual data. CSV fixtures have no fixture names.
The following example shows the format of a CSV fixture:
title,description, category one, post_one_desc, category_one two, post_two_desc, category_two
Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory appointed by ActiveSupport::TestCase.fixture_path=(path). Each text file placed in this directory represents a "record". Usually these types of fixtures are named without extensions.
The following example shows the format of a single-file fixture:
Fixtures are basically Hash objects. We can access the hash object directly because it is automatically setup as a local variable of the test case. For example:
# this will return the Hash for the fixture named post_one posts(:post_one)
For a small site, fixtures are enough. However, in bigger sites fixtures might get confusing. Factories are alternatives to fixtures in such cases. They have become increasingly popular in the last few years since they allow you to do things that cannot be done using YAML.
A factory is an object used to create other objects. Factory objects are used in test-driven development to allow the classes to be put under test.
Factory Girl is one of the well known factories which is widely used. It is written by Thoughtbot company and is available as a Ruby gem. Unlike fixtures, Factory Girl allows us to create objects rather than use defaults.
To set up Factory Girl, update the GemFile with the following
gem "factory_girl_rails", "~> 4.0"
The following example shows how a factory can be defined using Factory Girl:
Factory.define :post do |p| p.title 'Fixtures and Factories' p.description 'This a wiki for fixtures and factories' p.category 'OOLS' end
Fixtures vs. Factories
Fixtures allow known data to be statically pre-loaded into database tables before testing. Factories create only whatever is needed on a case by case basis.
- Easy to view all the data in one place
- Data is truly static
- Simple and clean
- Inserting data into the database for each run slows down the testing process
- Introduces dependency on fixture data
- Data customization is more complex
- Fixtures cannot be parameterized
- Maintains independence of tests
- Better overall performance since data is created only on a per need basis
- Tests and data are well isolated
- Complex relationships might be hard to capture
- Performance might sometimes be degraded, due to the create operations.
The article discusses how fixtures and factories are used with regard to testing. The different types of factories have been enumerated.The Factory Girl example is used to explain how factories are used. Different situations are explained where the use of fixtures and factories are contrasted. The advantages and disadvantages of both the approaches help throw some light on where the user must use fixtures and where the user must opt for factories.
- ↑ http://www.youtube.com/watch?v=OG8i9Udqm_s
- ↑ http://en.wikipedia.org/wiki/Unit_testing
- ↑ http://en.wikipedia.org/wiki/Functional_testing
- ↑ http://en.wikipedia.org/wiki/Integration_testing
- ↑ http://www.linuxjournal.com/magazine/forge-fixtures-and-factories?page=0,0
- ↑ http://ar.rubyonrails.org/classes/Fixtures.html
- ↑ http://en.wikipedia.org/wiki/YAML
- ↑ http://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures
- ↑ https://github.com/thoughtbot/factory_girl
- ↑ https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md