The approach I am presenting below is slightly different than the two original solutions - in the sense that my approach creates only one test, within which I cycle through the factories and run an assertion against each. I was not able to create a solution that mimics the original solutions any closer - which is (I believe) a separate test method for each factory. If someone could show such an implementation, that would be cool.
test/aaa_factories_tests/factories_test.rb
require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
class FactoriesTest < Minitest::Unit::TestCase
puts "\n*** Factories Test ***\n\n"
EXCEPTIONS = %w(name_of_a_factory_to_skip another_one_to_skip)
def test_factories
FactoryGirl.factories.each do |factory|
next if EXCEPTIONS.include?(factory.name.to_s)
instance = FactoryGirl.build(factory.name)
assert instance.valid?, "invalid factory: #{factory.name}, error messages: #{instance.errors.messages.inspect}"
instance = factory = nil
end
end
end
Thanks to the way Minitest
works out of the box -- add any directories under test/
and minitest-rails
will automatically create the associated rake task for it. So let's say you add a test/api/
directory, rake minitest:api
will automagically be available. -- I see the task when I run bundle exec rake -T
with no other configurations:
rake minitest:aaa_factories_tests # Runs tests under test/aaa_factories_tests
And I am able to run this task successfully:
-bash> bundle exec rake minitest:aaa_factories_tests
*** Factories Test ***
Run options: --seed 19208
# Running tests:
.
Finished tests in 0.312244s, 3.2026 tests/s, 9.6079 assertions/s.
1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
Despite the ugliness of prepending the directory with aaa
, I am able to have the factories tested first with:
bundle exec rake minitest:all
The reason for the aaa prepend solution is MiniTest
does a Dir
glob
and on Mac OS X
(and other Unix variants) the results are sorted alphabetically (though the results differ across different platforms).
As well, I prepended the default_tasks
array with aaa_factories_tests
to have the factories tested first in the default Minitest
task (i.e. when running bundle exec rake minitest
).
lib/tasks/factories_first.rake
MiniTest::Rails::Testing.default_tasks.unshift('aaa_factories_tests') if Rails.env =~ /^(development|test)\z/
Note that the above condition avoids erroneously referencing Minitest
in environments where it is unavailable (I have confined minitest-rails
to :test
and :development
groups in Gemfile
). Without this if
-condition, pushing to Heroku (for example to staging
or production
) will result in uninitialized constant MiniTest
.
Of course I am also able to run the factories test directly:
bundle exec ruby -I test test/aaa_factories_tests/factories_test.rb