Szukam sposobu na przyspieszenie moich testów Shoulda + FactoryGirl.Shoulda + FactoryGirl: Czy mogę przyspieszyć testy?
Model, który próbuję przetestować (StudentExam
) ma skojarzenia z innymi modelami. Te powiązane obiekty muszą istnieć przed utworzeniem StudentExam
. Z tego powodu są one tworzone w setup
.
Jednak utworzenie jednego z naszych modeli (School
) zajmuje dużo czasu. Ponieważ setup
jest wywoływana przed każdą instrukcją should
, cały test ma wykonać eony - tworzy nową instrukcję, której należy wykonać.
Poszukuję sposobu utworzenia tych obiektów po raz i tylko raz. Czy istnieje coś takiego, jak metoda startup
dla before_all
, która pozwoliłaby mi tworzyć rekordy, które będą się utrzymywać w pozostałej części sprawy testowej?
Zasadniczo szukam czegoś dokładnie takiego, jak RSPec's before(:all). Nie przejmuję się kwestią zależności, ponieważ testy te nigdy nie zmodyfikują tych drogich obiektów.
Oto przykładowy przypadek testowy. Przepraszam za długi kodu (Ja również stworzył 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
Najbardziej podoba mi się to podejście, ale wygląda na to, że nie działa prawidłowo. '@@ school = Factory (: school)' podnosi błąd sprawdzania poprawności, nazwa 'name' jest już zajęta (" validates_uniqueness_of "). Próbowałem używać '@@ school || = Factory (: school)' i będzie działać, jeśli testowa baza danych jest czysta. Więc skończyłem z super-brzydką '@@ school || = School.first || Factory (: school) ' –
Aby naprawić super-brzydkie obejście, odłóż ocenę za pomocą metody instancji. (zobacz moją edycję) –