Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Using nested-transactions to initialize test data programmatically.
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
test
.gitignore
CHANGELOG
LICENSE-MIT
README.rdoc
Rakefile
VERSION

README.rdoc

Transactional-factories

transactional-factories uses nested-transactions to allow efficient, programmatic initialization of test data.

Typical setup/teardown TestCase callbacks are called prior to every test method. Ruby's Test::Unit::TestCase wraps each test method in a transaction. If your test data must be created programmatically, the data creation code must be run prior to every test method. When the data creation code is slow, this will greatly increase the time it takes to run tests.

transactional-factories provides self.setup and self.teardown callbacks that are run only once for the entire testsuite. A file-level transaction is used to unwind any changes made in self.setup. Then any test methods are called in nested transactions (per normal TestCase behavior). This relies on database transactions so that we only have to run our data creation code once.

require 'transactional_factories'

class MyModelTest < Test::Unit::TestCase
  # Class method setup is called only once to create test data.
  def self.setup
    100.times { MyModel.create }
  end

  # Instance method setup is called before each test method (usual ruby behavior).
  def setup
    MyModel.create
  end

  def test_1
    assert_equal 101, MyModel.count
    MyModel.delete_all
    assert_equal 0, MyModel.count
  end

  def test_2
    assert_equal 101, MyModel.count
  end
end

Multiple Database Connections

If you have an application that connects to multiple databases, transactional-factories needs to create transactions for all of them. This is done at with another class-level accessor: TestCase.transaction_classes. In the example below two transactions (to two different databases) are created:

class MyModelTest < Test::Unit::TestCase

self.transaction_classes = [ModelWithDifferentDatabaseConnection, ActiveRecord::Base] end

Dependencies

nested transactional db - You must be using a database that supports nested transactions or savepoints. I've only tested on MySQL. Would be nice to have someone confirm this on PostgreSQL.

>= ActiveRecord 2.3.x - I don't think ActiveRecord supported nested transactions until 2.3.x.

use_transactional_fixtures = false - Your test cases can not use ActiveRecord transactional fixtures. Transactional fixtures wrap each test method in a transaction in such a way that does not allow nesting. Boo!

If you get this: TransactionalFactories::TransactionalFixturesEnabled, it's time to disable transactional fixtures doing something like this:

class ActiveSupport::TestCase
  self.use_transactional_fixtures = false
end
Something went wrong with that request. Please try again.