Have you ever added a seemingly innocent validation to a model, like so:
class User < ActiveRecord::Base
validates_presence_of :first_name
end
And then had this happen?:
$ rake spec

If you’re using FactoryGirl, this can often happen because you haven’t updated your factory to respect the new validation.
Of course, the fix is simple:
# spec/factories.rb
FactoryGirl.define do
factory :user do
first_name 'Jonah'
end
end
But how do you save yourself the time (and potential heart attack) of watching all those dreaded Fs go by?
My old solution used to be adding a boilerplate test in each model’s unit spec, like so:
# spec/models/user_spec.rb
describe User do
it 'has a valid Factory' do
build(:user).should be_valid
end
end
This is better than nothing, but it has two major problems.
Enter our savior, the factories_spec.rb:
# spec/factories_spec.rb
FactoryGirl.factories.map(&:name).each do |factory_name|
describe "The #{factory_name} factory" do
it 'is valid' do
build(factory_name).should be_valid
end
end
end
Fancytime! Now all our factory specs are in one place, DRY as a desert.
On to the second problem: we don’t want to wait for all our specs to run to deal with this error.
If you use rake to run your tests, one way to take care of this is by adding a pre-requisite to your rake spec task:
# Rakefile
desc 'Run factory specs.'
RSpec::Core::RakeTask.new(:factory_specs) do |t|
t.pattern = './spec/factories_spec.rb'
end
task spec: :factory_specs
Now the :factory_specs task will need to run and succeed before the whole suite is run. If you have a bad factory, you’ll know right away with a nice failure message:
$ rake spec

No more panic attacks necessary.

Just one of the many new things I’ve learned in my first day as a thoughtbot apprentice!