문제

나는 속도를 높이는 방법을 찾고 있습니다 멍청이 + FactoryGirl 테스트.

내가 테스트하려는 모델 (StudentExam)는 다른 모델과 연관성이 있습니다. 이러한 관련 객체는 내가 만들기 전에 존재해야합니다. StudentExam. 이런 이유로, 그것들은 만들어졌습니다 setup.

그러나 우리 모델 중 하나 (School) 생성하는 데 상당한 시간이 걸립니다. 왜냐하면 setup 매번 호출됩니다 should 성명서, 전체 테스트 사례는 Eons가 실행하는 데 필요합니다. 새로운 것을 만듭니다. @school, @student, @topic 그리고 @exam 모든 명세서에 대해 실행되었습니다.

한 번이 객체를 만들 수있는 방법을 찾고 있습니다. 그리고 한 번만. A와 같은 것이 있습니까? startup ~을 위한 before_all 테스트 사례의 나머지 부분에서 지속될 레코드를 만들 수있는 방법은 무엇입니까?

기본적으로 나는 RSPEC와 똑같은 것을 찾고 있습니다 전 (: All). 이 테스트는 그 비싼 물체를 결코 수정하지 않기 때문에 종속성 문제에 대해 걱정하지 않습니다.

다음은 예제 테스트 사례입니다. 긴 코드에 대한 사과 (나는 또한 요점):

# 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
도움이 되었습니까?

해결책

문제 가이 레코드를 한 번만 작성하는 경우 클래스 변수를 사용할 수 있습니다. 깨끗한 접근 방식은 아니지만 적어도 작동해야합니다.

# 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

  # 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)


  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

편집 : 인스턴스 메소드로 평가를 연기하는 수퍼 우주 해결 방법을 수정합니다.

# A StudentExam represents an Exam taken by a Student.
# It records the start/stop time, room number, etc.
class StudentExamTest < ActiveSupport::TestCase

  ...

  private

    def school
      @@school ||= Factory(:school)
    end

    # use school instead of @@school
    def student
      @@school ||= Factory(:student, :school => school)
    end

end

다른 팁

어떤 종류의 테스트를 작성하려고합니까? 실제로 이러한 모든 객체가 적절하게 조정하고 있는지 확인하려면 통합 테스트를 작성하고 속도가 주요 관심사가 아닙니다. 그러나 모델을 단위 테스트하려는 경우 적극적으로 스터브하여 더 나은 결과를 얻을 수 있습니다.

예를 들어, 시험에서 시험에서 시험에 전화 할 때 학교 협회의 이름을 사용하는지 확인하려는 경우 (또는 호출 할 때) 학교 대상이 필요하지 않습니다. 시험이 학교에서 올바른 방법을 호출하는지 확인하면됩니다. 테스트하기 위해 다음과 같은 작업을 수행 할 수 있습니다 (테스트 :: Unit 및 Mocha를 사용하여 내가 익숙하기 때문에) :

test "exam gets location from school name" do
  school = stub_everything
  school.expects(:name).returns(:a_school_name)
  exam = Factory(:exam, :school => school)

  assert_equal :a_school_name, exam.location
end

기본적으로 객체가 구성하기에는 너무 비싸기 때문에 단위 테스트 속도를 높이려면 실제로 장치 테스트가 아닙니다. 위의 모든 테스트 사례는 단위 테스트 레벨에 있어야한다고 생각하므로 스터브 스터브 스텁!

http://m.onkey.org/2009/9/20/make-your-shoulda-tests-faster-with-fast_context Fast_Context라는 보석을 사용하여 Doota/Factory-Girl 테스트를 더 빨리 만드는 방법에 대한 훌륭한 게시물입니다. 필요한 것이 아니라면 알려주세요.

호출 된 플러그인이 있습니다 FAST_CONTEXT (Github 링크))는 진술을 단일 컨텍스트로 결합하여 테스트 속도를 높여야합니다.

테스트 속도를 높이기 위해 사용한 또 다른 것은 고정물 데이터를 미리 인수하는 것입니다. FactoryGirl은 설정 블록이 실행될 때마다 해당 레코드를 생성하기 때문에 느립니다.

나는 플러그인을 썼다 고정 ActiveRecord를 사용하여 테스트 데이터베이스를 사전 인구를하므로 테스트에 필요한 레코드가 이미 작성되었습니다. 런타임에 새 레코드를 만들려면 Factorygirl과 함께 Fixie를 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top