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