test_seeds
Test Seeds allow efficient usage of object factories (like Factory Girl) in tests. Instead of creating objects for similar scenarios in each test case, Test Seeds start a db transaction for each test file, create all the common objects once, and then uses db savepoints for each test case allowing for the common objects to be re-used.
Description
Fixtures are a great way to get started. However, as your application becomes more complex, fixtures become a nightmare to manage and maintain. To alleviate this problem, people have flocked to object factories which allow creating complex testing scenarios right next to the code that tests those scenarios. Often similar scenarios are needed for a set of tests and the following pattern emerges,
class TestSomething < ActiveSupport::TestCase
setup :create_scenario
def create_scenario
@object_1 = ...create AR objects...
@object_2 = ...create AR objects...
@object_3 = ...create AR objects...
end
def test_case_1
end
...
def test_case_N
end
end
Sometimes creating the scenario in the setup callback, create_scenario is called by tests directly as needed. Either way, the problem is that create_scenario is called multiple times and creating objects via ActiveRecord is very slow. Test Seeds addresses this problem.
How It Works
Transactional fixtures work as follows,
test file do
load fixtures
transaction do
test case 1
end
transaction do
test case 2
end
transaction do
test case 3
end
end
Test Seeds piggy backs on the transaction fixtures functionality. Test Seeds load fixtures into the database in the same way but then start a db transaction for the duration of the test file. Any objects for the common scenarios are then created and inserted into the database. Test Seeds then execute each test case within a context of a db savepoint (or nested db transactions). This allows test seeds to be inserted into the database once and then re-used for each test case that needs it. Here is the pseudo code,
test file do
load fixtures
transaction do
load seeds
savepoint do
test case 1
end
savepoint do
test case 2
end
savepoint do
test case 3
end
end
end
How To Use
There are two main ways of using Test Seeds. The first way makes all the seeds available to all the tests,
class TestSomething < ActiveSupport::TestCase
include TestSeeds
seeds do
@object_1 = ...create AR objects...
@object_2 = ...create AR objects...
@object_3 = ...create AR objects...
end
def test_case_1
# @object_1, @object_2, and @object_3 are available here
end
...
def test_case_N
# @object_1, @object_2, and @object_3 are available here
end
end
Alternatively, you can be more selective which seeds go with which test cases,
class TestSomething < ActiveSupport::TestCase
include TestSeeds
seeds(:scenario_a) do
@object_a1 = ...create AR objects...
@object_a2 = ...create AR objects...
@object_a3 = ...create AR objects...
end
seeds(:scenario_b) do
@object_b1 = ...create AR objects...
@object_b2 = ...create AR objects...
@object_b3 = ...create AR objects...
end
def test_case_1
setup_seeds(:scenario_a)
# @object_a1, @object_a2, and @object_a3 are available here
end
def test_case_2
setup_seeds(:scenario_b)
# @object_b1, @object_b2, and @object_b3 are available here
end
def test_case_3
setup_seeds(:scenario_a, :scenario_b)
# @object_a1, @object_a2, and @object_a3 are available here
# @object_b1, @object_b2, and @object_b3 are available here
end
end
Contributing to test_seeds
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright © 2011 Paul Kmiec. See LICENSE.txt for further details.