我在寻找一种方式来加快我的早该 +的 FactoryGirl 测试。

我想测试(StudentExam)的模型和关联到其他车型。这些关联的对象必须存在,我可以创造一个StudentExam。出于这个原因,它们在setup创建的。

然而,我们的模型(School)之一需要显著的时间来创建。因为setup得到每should语句之前调用,整个测试情况需要亿万年来执行 - 它会创建一个新的@school@student@topic@exam每一个应声明执行

我在寻找一种方式来一次创建这些对象的只有一次的。有什么样的startup方法before_all,让我创造这将在整个测试案例的休息吗?

坚持记录

基本上我寻找的东西完全一样的RSpec的之前(:所有)。我不担心,因为依赖这些测试将永远不会修改这些昂贵的对象的问题。

下面是一个例子测试用例。道歉用于长码(我还创建了一个要旨):

# 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

其他提示

什么样的测试,你想写?如果你真的想确保所有这些对象进行适当的协调,你正在写一个集成测试和速度是不是你首要关注的问题。不过,如果你想单元测试的模型,你可以通过积极磕碰达到更好的效果。

例如,如果你想检查考试使用其学校协会的名称,当你调用exam.location(或任何你要调用它),你并不需要一个全校对象。你只需要确保考试呼吁学校正确的方法。为了验证这一点,你可以不喜欢以下(使用测试::单位和摩卡因为那是我熟悉):

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://米.onkey.org / 2009/9/20 /化妆你,早该检验更快的与 - fast_context 是如何使你早该/工厂女孩测试更快的优秀岗位,使用的宝石叫fast_context 。让我知道,如果它不是你所需要的。

有一种称为插件 fast_context GitHub的链接)相结合的语句应该到一个单一的背景下,加快测试

我一直在使用,以加快我的测试的另一件事是预先填充夹具数据。 FactoryGirl是缓慢的,因为它创建每个安装块运行时间的记录。

我写了一个称为 Fixie 使用ActiveRecord的预填充的测试数据库,所以插件你需要为你的测试记录已创建。如果你想创建在运行时的新记录,也可以使用Fixie与FactoryGirl一起。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top