Estoy buscando una manera de acelerar mis Shoulda + FactoryGirl pruebas.Shoulda + FactoryGirl: ¿Puedo hacer que mis pruebas sean más rápidas?
El modelo que estoy tratando de probar (StudentExam
) tiene asociaciones con otros modelos. Estos objetos asociados deben existir antes de que pueda crear un StudentExam
. Por esa razón, se crean en setup
.
Sin embargo, uno de nuestros modelos (School
) lleva mucho tiempo crearlo. Como se llama a setup
antes de cada instrucción should
, todo el caso de prueba tarda mucho en ejecutarse: crea un nuevo @school
, @student
, @topic
y @exam
por cada declaración de deber ejecutada.
Estoy buscando una forma de crear estos objetos una vez y una sola vez. ¿Hay algo así como un método startup
para before_all
que me permita crear registros que persistirán durante el resto del caso de prueba?
Básicamente estoy buscando algo exactamente como RSpec before(:all). No me preocupa el tema de las dependencias, ya que estas pruebas nunca modificarán esos objetos caros.
Aquí hay un ejemplo de caso de prueba. Disculpas por el código largo (También he creado un 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 [email protected]_exam.in_progress
end
end
end
Me gusta más este enfoque, pero parece que no funciona correctamente. '@@ school = Factory (: school)' genera un error de validación, que 'name' ya está tomado (it' validates_uniqueness_of'). Intenté usar '@@ school || = Factory (: school)' y funcionará si la base de datos de prueba está limpia. Así que terminé con la super-fea '@@ school || = School.first || Factory (: school) ' –
Para solucionar la solución súper fea, posponga la evaluación con un método de instancia. (ver mi edición) –