Wednesday, July 8, 2009

Some of the useful way of using fixture better

1. Using new fixture facilities in rails 2.(example)

    Which will remove the relational fixtures for has_many :through and has_and_belongs_to_many relations.

    It will remove the ids and will give a better way of relating between tables.

2. Fixtures are read only:    Never modify any existing fixture, unless your database schema has changed.    Which also indicates that we should be very careful when are adding a new fixture.

3. Another way to identify if the fixture is well written is that they all should be meaningful.    And none of them should look similar.

   If a different fixture is needed for only 1 or 2 test, then update existing before doing the test.    For an example,

should 'assign responsible person to unassigned task' do
    task = tasks(:task_not_started)
    task.users.clear #clear the existing fixture(not creating a new one for that fixture) 

    assign_and_assert_responsible_person(task, users(:login_user))
end
This will reduce the number of fixture set and keep them clean.

4. Often we write test codes that involves a lot of fixture.    Some times when we get test fail, we run through the fixtures, trying to find out which went wrong.    But instead if we comment our code such a way that the fixture is understood from the test code,    then that would be even better. Like,

context 'in progress task' do
  setup do
    @task = tasks(:task_in_progress)
    # task -> time_estimates
    #         [ user: login_user, hours_spent: 2, hours_remaining: 8, entry_date: 1.days.ago ]
    #         [ user: developer , hours_spent: 4, hours_remaining: 3, entry_date: Date.today ]
  end

  should 'return hours spent upto' do
    assert_equal(2, @task.hours_spent_upto(1.days.ago))
    assert_equal(6, @task.hours_spent_upto(Date.today))
  end
end
5. Inherit fields, that are less likely to be different for each fixture
backlog_item: &common_backlog_fields
  project_id: scrumpad
  type: Story

bug:
  <<: *common_backlog_fields
  type: Bug
  title: Test Bug
  content: Bug content
  created_at: <%= 10.days.ago.to_s(:db) %>
  updated_at: <%= 3.days.ago.to_s(:db) %>

story:
  <<: *common_backlog_fields
  title: Sample story
  state: <%= WorkItem::COMPLETED %>
  created_at: <%= 10.days.ago.to_s(:db) %>
  updated_at: <%= 2.days.ago.to_s(:db) %>
Here we can define the common required fields in backlog_item and use that definition for other fixtures. The fields can be overwritten by redefining in the fixtures as we did overwritten type for bug.

1 comment:

Unknown said...

Good guidelines for using test fixtures. I was wondering if it was possible to create a simple rake task to update all fixture files. For example, I want look into all work_items.yml file and replace the word status_id: with state: with a command like
rake update_fixture work_items.yml status_id:=>state: