Je suis à la recherche d'un moyen d'accélérer mes tests + FactoryGirl.Shoulda + FactoryGirl: Puis-je faire mes tests plus rapidement?
Le modèle que j'essaie de tester (StudentExam
) a des associations avec d'autres modèles. Ces objets associés doivent exister avant que je puisse créer un StudentExam
. Pour cette raison, ils sont créés en setup
.
Cependant, un de nos modèles (School
) prend beaucoup de temps à créer. Parce que setup
est appelée avant chaque instruction should
, le test complet prend des éons à exécuter - il crée un nouveau @school
, @student
, @topic
et @exam
pour chaque instruction should exécutée.
Je cherche un moyen de créer ces objets une fois et seulement une fois. Y a-t-il quelque chose comme une méthode startup
pour before_all
qui me permettrait de créer des enregistrements qui persisteront dans le reste du cas de test?
Fondamentalement, je suis à la recherche de quelque chose exactement comme before(:all) de RSpec. Je ne suis pas concerné par le problème des dépendances car ces tests ne modifieront jamais ces objets coûteux.
Voici un exemple de cas de test. Toutes mes excuses pour le long code (j'ai aussi créé 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
J'aime mieux cette approche, mais elle ne semble pas fonctionner correctement. '@@ school = Factory (: school)' soulève une erreur de validation, que 'name' est déjà pris (il' validates_uniqueness_of'). J'ai essayé d'utiliser '@@ school || = Factory (: school)' et cela fonctionnera si la base de données de test est propre. Donc j'ai fini avec le super-laid '@@ school || = School.first || Factory (: school) ' –
Pour résoudre la solution super-laid retarder l'évaluation avec une méthode d'instance. (Voir mon édition) –