I'm looking for a way to speed up my Shoulda + FactoryGirl tests.
The model I'm trying to test (StudentExam
) has associations to other models. These associated objects must exist before I can create a StudentExam
. For that reason, they are created in setup
.
However, one of our models (School
) takes significant time to create. Because setup
gets called before every should
statement, the entire test case takes eons to execute -- it creates a new @school
, @student
, @topic
and @exam
for every should statement executed.
I'm looking for a way to create these objects once and only once. Is there something like a startup
for before_all
method that would allow me to create records which will persist throughout the rest of the test case?
Basically I'm looking for something exactly like RSpec's before(:all). I'm not concerned about the issue of dependencies since these tests will never modify those expensive objects.
Here's an example test case. Apologies for the long code (I've also created a gist):
# A StudentExam represents an Exam taken by a Student.
# It records the start/stop time, room number, etc.
class StudentExamTest < ActiveSupport::TestCase
should_belong_to :student
should_belong_to :exam
setup do
# These objects need to be created before we can create a StudentExam. Tests will NOT modify these objects.
# @school is a very time-expensive model to create (associations, external API calls, etc).
# We need a way to create the @school *ONCE* -- there's no need to recreate it for every single test.
@school = Factory(:school)
@student = Factory(:student, :school => @school)
@topic = Factory(:topic, :school => @school)
@exam = Factory(:exam, :topic => @topic)
end
context "A StudentExam" do
setup do
@student_exam = Factory(:student_exam, :exam => @exam, :student => @student, :room_number => "WB 302")
end
should "take place at 'Some School'" do
assert_equal @student_exam, 'Some School'
end
should "be in_progress? when created" do
assert @student_exam.in_progress?
end
should "not be in_progress? when finish! is called" do
@student_exam.finish!
assert !@student_exam.in_progress
end
end
end