测试 用 FactoryGirl seed 改善重复创建问题和用例执行慢的问题

caiqinghua · 2015年07月15日 · 最后由 emanon 回复于 2015年07月17日 · 2611 次阅读

本文上下文环境

Rails 测试驱动开发 Factory Girl 用例重构实践

factory_girl-seeds 简介

factory_girl-seeds github 官网

FactoryGirl Seeds Don't like factory_girl because it is slow? Do you know that creating records in DB through factory_girl can take up to 50% of total spec run time? And even more!

This tiny gem helps fix that problem by reusing data preloaded before running test suite.

好处:

  • 加快用例执行速度
  • 对我们的附加作用:解决重复创建问题

用 factory_girl-seeds 重构代码前后比较

重构后代码

spec/support/login_helpers.rb

module LoginHelpers

  def login_staff
    before(:each) do
      staff = create(:staff)
      controller.send(:login_as, staff)
    end
  end

  def login_user
    before(:each) do
      user = create(:user)
      controller.send(:login_as, user)
    end
  end

  def login_as_seller_user
    before(:each) do
      user = seed(:seller_user)
      controller.send(:login_as, user)
    end
  end

  def login_super_admin
    before(:each) do
      super_admin = seed(:super_admin)
      controller.send(:login_as, super_admin)
    end
  end

  def login_h_company_admin_staff
    before(:each) do
      h_company_admin_staff = seed(:h_company_admin_staff)
      controller.send(:login_as, h_company_admin_staff)
    end
  end

  def login_h_company_normal_staff
    before(:each) do
      b_company_normal_staff = seed(:h_company_normal_staff)
      controller.send(:login_as, b_company_normal_staff)
    end
  end

end
FactoryGirl.define do

  factory :staff, aliases: [:random_staff] do
    mobile
    password '1' * 6
    name { generate(:random_name) }

    trait :super_admin do
      after(:create) { |staff| staff.add_role(seed(:staff_super_admin_role).name) }
    end

    trait :company_admin do
      after(:create) { |staff| staff.add_role(seed(:staff_company_admin_role).name) }
    end

    trait :normal_staff do
      after(:create) { |staff| staff.add_role(seed(:staff_normal_role).name) }
    end

    trait :h_company do 
      after(:create) do |staff|
        staff.company = seed(:h_company)
        staff.save
      end
    end

    trait :b_company do 
      after(:create) do |staff| 
        staff.company = seed(:b_company) 
        staff.save
      end
    end

    factory :super_admin, traits: [:super_admin, :h_company]

    factory :h_company_admin_staff, traits: [:h_company, :company_admin]
    factory :h_company_normal_staff, traits: [:h_company, :normal_staff]

    factory :b_company_admin_staff, traits: [:b_company, :company_admin]
    factory :b_company_normal_staff, traits: [:b_company, :normal_staff]

  end
end
spec/rails_helper.rb

config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
    prepare_factory_girl_seed_data
  end

def prepare_factory_girl_seed_data
  FactoryGirl::SeedGenerator.create(:user_role_h)
  FactoryGirl::SeedGenerator.create(:user_role_b)
  FactoryGirl::SeedGenerator.create(:user_role_t)
  FactoryGirl::SeedGenerator.create(:user_role_c)

  FactoryGirl::SeedGenerator.create(:h_user)
  FactoryGirl::SeedGenerator.create(:b_user)
  FactoryGirl::SeedGenerator.create(:t_user)
  FactoryGirl::SeedGenerator.create(:c_user)

  FactoryGirl::SeedGenerator.create(:h_company)
  FactoryGirl::SeedGenerator.create(:b_company)
  FactoryGirl::SeedGenerator.create(:terminal_company)
  FactoryGirl::SeedGenerator.create(:cloud_company)

  FactoryGirl::SeedGenerator.create(:staff_super_admin_role)
  FactoryGirl::SeedGenerator.create(:staff_company_admin_role)
  FactoryGirl::SeedGenerator.create(:staff_normal_role)

  FactoryGirl::SeedGenerator.create(:super_admin)
  FactoryGirl::SeedGenerator.create(:h_company_admin_staff)
  FactoryGirl::SeedGenerator.create(:h_company_normal_staff)
  FactoryGirl::SeedGenerator.create(:b_company_admin_staff)
  FactoryGirl::SeedGenerator.create(:b_company_normal_staff)
end

新来了个刷屏狂。一阵一阵的。

caiqinghua Rails 测试驱动开发 Factory Girl 用例重构实践 提及了此话题。 07月22日 10:58
需要 登录 后方可回复, 如果你还没有账号请 注册新账号