簡體   English   中英

為什么我在ONE型號上進行rspec Rails測試需要10分鍾? (Rails 3.2 / rspec 2 / Guard / spork)

[英]Why do my rspec Rails tests on ONE model is taking 10 minutes ?! (Rails 3.2/rspec 2/Guard/spork)

我在我的應用程序中定義了rspec測試,但是它們已經花了很多年了! 在我的整個應用程序中,我在37分鍾內運行了438個測試。 每分鍾只有10次測試。

我將Guard用作rspec,Spork,所以我認為它應該更快。 一定有什么不對勁。

例如,模型“ Prize”上的rspec測試需要134分鍾進行13分鍾的測試。 太慢了! 這是我對獎品的說明:

require 'spec_helper'

describe Prize do
  let(:admin_user) { FactoryGirl.create(:admin_user) }

  before(:each) do
    @attr = {
      prize_name: "lorem ipsum",
      prize_short_description_for_modals: "yokoko gygy gygy",
      prize_long_description_for_rules_and_user_account:  "longer better longer better longer better",
      prize_detailed_webpage_url: "http://www.example.com",
      prize_image_url: "http://www.example2.com",
      prize_image_alt:"French",
      prize_type: "Jackpot prize",
      prize_initial_stock_quantity: 100,
      prize_remaining_stock_quantity: 5,
      prize_unit_certified_market_value:  450,
      prize_date_for_certified_market_value: 2.days.from_now,
      prize_displayed_value_on_website: 456,
      prize_require_additional_user_info: true,
      prize_max_nb_days_for_claiming: 24,
      prize_expiry_date: 75.days.from_now,
      prize_category: "computer",
      prize_sourcer_company_name: "Nefertiti",
      prize_sourcer_contact_point_name: "Gentle Man",
      prize_sourcer_contact_point_direct_phone: "01 45 67 68 77",
      prize_sourcer_contact_point_email: "gentle.man@example.com",
      prize_sourcer_how_to_contact_details: "From 9 TO 5pm, Mon. to Fri.",
      prize_sourcer_crm_profile_url: "http://www.example3com",
      prize_fully_stocked_validated:  true,
      # admin_user_id: 1,
      # as: :admin_user
    }
  end

    it { should respond_to(:prize_name) }
    it { should respond_to(:prize_short_description_for_modals) }
    it { should respond_to(:prize_long_description_for_rules_and_user_account) }
    it { should respond_to(:prize_detailed_webpage_url) }
    it { should respond_to(:prize_image_url) }
    it { should respond_to(:prize_image_alt) }
    it { should respond_to(:prize_type) }
    it { should respond_to(:prize_initial_stock_quantity) }
  it { should respond_to(:prize_remaining_stock_quantity) }
  it { should respond_to(:prize_unit_certified_market_value) }
  it { should respond_to(:prize_date_for_certified_market_value) }
  it { should respond_to(:prize_displayed_value_on_website) }
  it { should respond_to(:prize_require_additional_user_info) }
  it { should respond_to(:prize_max_nb_days_for_claiming) }
  it { should respond_to(:prize_expiry_date) }
  it { should respond_to(:prize_category) }
  it { should respond_to(:prize_sourcer_company_name) }
  it { should respond_to(:prize_sourcer_contact_point_name) }
  it { should respond_to(:prize_sourcer_contact_point_direct_phone) }
  it { should respond_to(:prize_sourcer_contact_point_email) }
  it { should respond_to(:prize_sourcer_how_to_contact_details) }
  it { should respond_to(:prize_sourcer_crm_profile_url) }
  it { should respond_to(:prize_fully_stocked_validated) }

    it { should respond_to(:admin_user_id) }
    it { should respond_to(:deal_id) }
    # its(:admin_user) { should == admin_user }

    # it { should be_valid }

  # it "should create a new instance given a valid attribute" do
  #   prize.create!(@attr)
  # end

  # -- Active Records Tests --------------------------------------------------------
  describe "tests on prize's active record" do
    it { should belong_to(:admin_user).with_foreign_key('admin_user_id')  }
    it { should belong_to(:deal) }
  end

  # Tests on Mass-Assginement
    describe "tests on prize's attributes mass assignement" do
      it { should allow_mass_assignment_of(:prize_name) }
      it { should allow_mass_assignment_of(:prize_short_description_for_modals) }
      it { should allow_mass_assignment_of(:prize_long_description_for_rules_and_user_account) }
      it { should allow_mass_assignment_of(:prize_detailed_webpage_url) }
      it { should allow_mass_assignment_of(:prize_image_url) }
      it { should allow_mass_assignment_of(:prize_image_alt) }
      it { should allow_mass_assignment_of(:prize_type) }
      it { should allow_mass_assignment_of(:prize_initial_stock_quantity) }
      it { should allow_mass_assignment_of(:prize_remaining_stock_quantity) }
      it { should allow_mass_assignment_of(:prize_unit_certified_market_value) }
      it { should allow_mass_assignment_of(:prize_date_for_certified_market_value) }
      it { should allow_mass_assignment_of(:prize_displayed_value_on_website) }
      it { should allow_mass_assignment_of(:prize_require_additional_user_info) }
      it { should allow_mass_assignment_of(:prize_max_nb_days_for_claiming) }
      it { should allow_mass_assignment_of(:prize_expiry_date) }
      it { should allow_mass_assignment_of(:prize_category) }
      it { should allow_mass_assignment_of(:prize_sourcer_company_name) }
      it { should allow_mass_assignment_of(:prize_sourcer_contact_point_name) }
      it { should allow_mass_assignment_of(:prize_sourcer_contact_point_email) }
      it { should allow_mass_assignment_of(:prize_sourcer_contact_point_direct_phone) }
      it { should allow_mass_assignment_of(:prize_sourcer_how_to_contact_details) }
      it { should allow_mass_assignment_of(:prize_sourcer_crm_profile_url) }
      it { should allow_mass_assignment_of(:prize_fully_stocked_validated) }

      it { should_not allow_mass_assignment_of(:admin_user_id) }
      it { should_not allow_mass_assignment_of(:deal_id) }

      it { should allow_mass_assignment_of(:admin_user_id).as(:admin_user) }
      it { should allow_mass_assignment_of(:deal_id).as(:admin_user) }
    end

  # -- Controller Tests --------------------------------------------------------
  describe "tests on prize's controllers" do
  end

  # -- Models Tests --------------------------------------------------------
  describe "tests on prize's models validations for prize_name" do
    it { should validate_presence_of(:prize_name) }
    it { should_not allow_value(" ").for(:prize_name) }

    it "should reject prize with names that are too long" do
      long = "a" * 101
      hash = @attr.merge(:prize_name => long)
      Prize.new(hash).should have(1).error_on(:prize_name)
    end

    it "should reject prize with names that are too short" do
      short = "a" * 4
      hash = @attr.merge(:prize_name => short)
      Prize.new(hash).should have(1).error_on(:prize_name)
    end
  end

  describe "tests on prize's models validations for prize_short_description_for_modals" do
    it { should validate_presence_of(:prize_short_description_for_modals) }
    it { should_not allow_value(" ").for(:prize_short_description_for_modals) }

    it "should reject attribute that are too long" do
      long = "a" * 301
      hash = @attr.merge(:prize_short_description_for_modals => long)
      Prize.new(hash).should have(1).error_on(:prize_short_description_for_modals)
    end

    it "should reject attribute that are too short" do
      short = "a" * 9
      hash = @attr.merge(:prize_short_description_for_modals => short)
      Prize.new(hash).should have(1).error_on(:prize_short_description_for_modals)
    end
  end

  describe "tests on prize's models validations for prize_long_description_for_rules_and_user_account" do
    it { should validate_presence_of(:prize_long_description_for_rules_and_user_account) }
    it { should_not allow_value(" ").for(:prize_long_description_for_rules_and_user_account) }

    it "should reject attribute that are too long" do
      long = "a" * 10001
      hash = @attr.merge(:prize_long_description_for_rules_and_user_account => long)
      Prize.new(hash).should have(1).error_on(:prize_long_description_for_rules_and_user_account)
    end

    it "should reject attribute that are too short" do
      short = "a" * 9
      hash = @attr.merge(:prize_long_description_for_rules_and_user_account => short)
      Prize.new(hash).should have(1).error_on(:prize_long_description_for_rules_and_user_account)
    end
  end

  describe "tests on prize's models validations for prize_detailed_webpage_url" do
    it { should validate_presence_of(:prize_detailed_webpage_url) }
    it { should_not allow_value(" ").for(:prize_detailed_webpage_url) }
    it { should_not allow_value("string but not url").for(:prize_detailed_webpage_url) }   
  end

  describe "tests on prize's models validations for prize_image_url" do
    it { should validate_presence_of(:prize_image_url) }
    it { should validate_uniqueness_of(:prize_image_url).case_insensitive }
    it { should_not allow_value(" ").for(:prize_image_url) }
    it { should_not allow_value("stringbutnoturl").for(:prize_image_url) }     
  end

  describe "tests on prize's models validations for prize_image_alt" do
    it { should validate_presence_of(:prize_image_alt) }
    it { should_not allow_value(" ").for(:prize_image_alt) }

    it "should reject attribute that are too long" do
      long = "a" * 31
      hash = @attr.merge(:prize_image_alt => long)
      Prize.new(hash).should have(1).error_on(:prize_image_alt)
    end
  end

  describe "tests on prize's models validations for prize_type" do
    it { should validate_presence_of(:prize_type) }
    it { should_not allow_value(" ").for(:prize_type) }
    it { should ensure_inclusion_of(:prize_type).in_array(PRIZE_TYPES) }
  end

  describe "tests on prize's models validations for prize_initial_stock_quantity" do
    it { should validate_presence_of(:prize_initial_stock_quantity) }
    it { should_not allow_value(" ").for(:prize_initial_stock_quantity) }

    it { should validate_numericality_of(:prize_initial_stock_quantity).only_integer }
    it { should validate_numericality_of(:prize_initial_stock_quantity).is_greater_than_or_equal_to(1) }
  end

  describe "tests on prize's models validations for prize_unit_certified_market_value" do
    it { should validate_presence_of(:prize_unit_certified_market_value) }
    it { should_not allow_value(" ").for(:prize_unit_certified_market_value) }

    it { should validate_numericality_of(:prize_unit_certified_market_value).only_integer }
    it { should validate_numericality_of(:prize_unit_certified_market_value).is_greater_than_or_equal_to(1) }
    it { should validate_numericality_of(:prize_unit_certified_market_value).is_less_than_or_equal_to(1000000) }
  end

  describe "tests on prize's models validations for prize_date_for_certified_market_value" do
    it { should validate_presence_of(:prize_date_for_certified_market_value) }
    it { should_not allow_value(Time.zone.today - 1).for(:prize_date_for_certified_market_value).on(:create) } # has to be at least today
  end

  describe "tests on prize's models validations for prize_require_additional_user_info" do
    it { should validate_presence_of(:prize_require_additional_user_info) }
    it { should ensure_inclusion_of(:prize_require_additional_user_info).in_array(%w(true false)) }
  end

  describe "tests on prize's models validations for prize_max_nb_days_for_claiming" do
    it { should validate_presence_of(:prize_max_nb_days_for_claiming) }
    it { should_not allow_value(" ").for(:prize_max_nb_days_for_claiming) }

    it { should validate_numericality_of(:prize_max_nb_days_for_claiming).only_integer }
    it { should validate_numericality_of(:prize_max_nb_days_for_claiming).is_greater_than_or_equal_to(7) }
    it { should validate_numericality_of(:prize_max_nb_days_for_claiming).is_less_than_or_equal_to(90) }
  end

  describe "tests on prize's models validations for prize_expiry_date" do
    it { should_not allow_value(Time.zone.today - 1).for(:prize_expiry_date).on(:create) } # has to be at least today
  end

  describe "tests on prize's models validations for prize_category" do
    it { should validate_presence_of(:prize_category) }
    it { should_not allow_value(" ").for(:prize_category) }
    it { should ensure_inclusion_of(:prize_category).in_array(PRIZE_CATEGORIES) }
  end

  describe "tests on prize's models validations for prize_sourcer_company_name" do

    it "should reject attribute that are too long" do
      long = "a" * 101
      hash = @attr.merge(:prize_sourcer_company_name => long)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_company_name)
    end

    it "should reject attribute that are too short" do
      short = "a" * 2
      hash = @attr.merge(:prize_sourcer_company_name => short)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_company_name)
    end
  end

  describe "tests on prize's models validations for prize_sourcer_contact_point_name" do

    it { should validate_presence_of(:prize_sourcer_contact_point_name) }
    it { should_not allow_value(" ").for(:prize_sourcer_contact_point_name)}

    it "should reject attribute that are too long" do
      long = "a" * 101
      hash = @attr.merge(:prize_sourcer_contact_point_name => long)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_contact_point_name)
    end

    it "should reject attribute that are too short" do
      short = "a" * 2
      hash = @attr.merge(:prize_sourcer_contact_point_name => short)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_contact_point_name)
    end
  end

  describe "tests on prize's models validations for prize_sourcer_contact_point_direct_phone" do

    context "if prize_sourcer_contact_point_name present" do # test when sourcer is present
      before { subject.stub(:prize_sourcer_company_name?) { true } }
      it { should validate_presence_of(:prize_sourcer_contact_point_direct_phone) }
      it { should_not allow_value(" ").for(:prize_sourcer_contact_point_direct_phone) }
    end 

    context "if prize_sourcer_contact_point_name not present" do # test when sourcer is not present
      before { subject.stub(:prize_sourcer_company_name?) { false } }
      it { should_not validate_presence_of(:prize_sourcer_contact_point_direct_phone) }
    end 

    it "should reject attribute that are too long" do
      long = "a" * 21
      hash = @attr.merge(:prize_sourcer_contact_point_direct_phone => long)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_contact_point_direct_phone)
    end

    it "should reject attribute that are too short" do
      short = "a" * 3
      hash = @attr.merge(:prize_sourcer_contact_point_direct_phone => short)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_contact_point_direct_phone)
    end
  end

  describe "tests on prize's models validations for prize_sourcer_contact_point_email" do

    context "if prize_sourcer_contact_point_name present" do # test when sourcer is present
      before { subject.stub(:prize_sourcer_company_name?) { true } }
      it { should validate_presence_of(:prize_sourcer_contact_point_email) }
      it { should_not allow_value(" ").for(:prize_sourcer_contact_point_email) }
      it { should_not allow_value("blah").for(:prize_sourcer_contact_point_email) } # need to include format with @
    end 

    context "if prize_sourcer_contact_point_name not present" do # test when sourcer is not present
      before { subject.stub(:prize_sourcer_company_name?) { false } }
      it { should_not validate_presence_of(:prize_sourcer_contact_point_email)  }
    end 

    it "should reject attribute that are too long" do
      long = "a@" * 51
      hash = @attr.merge(:prize_sourcer_contact_point_email => long)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_contact_point_email)
    end

  end

  describe "tests on prize's models validations for prize_sourcer_how_to_contact_details" do

    context "if prize_sourcer_contact_point_name present" do # test when sourcer is present
      before { subject.stub(:prize_sourcer_company_name?) { true } }
      it { should validate_presence_of(:prize_sourcer_how_to_contact_details) }
      it { should_not allow_value(" ").for(:prize_sourcer_how_to_contact_details) }
    end 

    context "if prize_sourcer_contact_point_name not present" do # test when sourcer is not present
      before { subject.stub(:prize_sourcer_company_name?) { false } }
      it { should_not validate_presence_of(:prize_sourcer_how_to_contact_details)  }
    end 

    it "should reject attribute that are too long" do
      long = "a" * 501
      hash = @attr.merge(:prize_sourcer_how_to_contact_details => long)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_how_to_contact_details)
    end

    it "should reject attribute that are too short" do
      short = "a" * 3
      hash = @attr.merge(:prize_sourcer_how_to_contact_details => short)
      Prize.new(hash).should have(1).error_on(:prize_sourcer_how_to_contact_details)
    end
  end

  describe "tests on prize's models validations for prize_sourcer_crm_profile_url" do

    context "if sourcer present" do # test when sourcer is present
      before { subject.stub(:prize_sourcer_company_name?) { true } }
      it { should validate_presence_of(:prize_sourcer_crm_profile_url) }
      it { should_not allow_value(" ").for(:prize_sourcer_crm_profile_url) }
      it { should_not allow_value("stringbuturl").for(:prize_sourcer_crm_profile_url) }
    end 

    context "if sourcer not present" do # test when sourcer is not present
      before { subject.stub(:prize_sourcer_company_name?) { false } }
      it { should_not validate_presence_of(:prize_sourcer_crm_profile_url) }
    end 
  end

  describe "tests on prize's models validations for prize_fully_stocked_validated" do
    # it { should validate_presence_of(:prize_fully_stocked_validated) }
    # it { should ensure_inclusion_of(:prize_fully_stocked_validated).in_array(%w(true false)) }
  end

  describe "tests on prize's models validations for admin_user_id" do
     it { should validate_presence_of(:admin_user_id) }
     it { should_not allow_mass_assignment_of(:admin_user_id) }
     it { should allow_mass_assignment_of(:admin_user_id).as(:admin_user) }
     it { should validate_numericality_of(:admin_user_id) }
  end  

  describe "tests on prize's models validations for deal_id" do
     it { should validate_presence_of(:deal_id) }
     it { should_not allow_mass_assignment_of(:deal_id) }
     it { should allow_mass_assignment_of(:deal_id).as(:admin_user) }
     it { should validate_numericality_of(:deal_id) }
  end 

end

我已經調整了垃圾收集器( http://makandracards.com/makandra/950-speed-up-rspec-by-deferring-garbage-collection ),但幾乎沒有效果。

class DeferredGarbageCollection

  DEFERRED_GC_THRESHOLD = (ENV['DEFER_GC'] || 10.0).to_f

  @@last_gc_run = Time.now

  def self.start
    GC.disable if DEFERRED_GC_THRESHOLD > 0
  end

  def self.reconsider
    if DEFERRED_GC_THRESHOLD > 0 && Time.now - @@last_gc_run >= DEFERRED_GC_THRESHOLD
      GC.enable
      GC.start
      GC.disable
      @@last_gc_run = Time.now
    end
  end
end

我使用https://github.com/tmm1/perftools.rb來評估花費的時間並了解為什么要花費這么長時間。 這是perftools的分析

Total: 533 samples
      45   8.4%   8.4%       45   8.4% garbage_collector
      38   7.1%  15.6%       40   7.5% String#gsub
      35   6.6%  22.1%       35   6.6% String#=~
      20   3.8%  25.9%       20   3.8% Hash#initialize_copy
      15   2.8%  28.7%       29   5.4% Enumerable#inject
      14   2.6%  31.3%      201  37.7% I18n::Backend::Base#translate
      13   2.4%  33.8%      203  38.1% Kernel#catch
      13   2.4%  36.2%       18   3.4% URI::Parser#make_regexp
      12   2.3%  38.5%       12   2.3% PG::Connection#async_exec
      10   1.9%  40.3%      483  90.6% Array#map
       9   1.7%  42.0%       18   3.4% ActiveRecord::DynamicMatchers#respond_to?
       9   1.7%  43.7%        9   1.7% Hash#has_key?
       9   1.7%  45.4%        9   1.7% String#gsub!
       7   1.3%  46.7%        7   1.3% Class#logger
       7   1.3%  48.0%        7   1.3% Regexp#match
       6   1.1%  49.2%       12   2.3% #<Module:0x00000002cbf5a0>#normalize_key
       6   1.1%  50.3%       64  12.0% ActiveModel::Translation#human_attribute_name
       6   1.1%  51.4%        6   1.1% Kernel#is_a?
       6   1.1%  52.5%        7   1.3% Kernel.Float
       6   1.1%  53.7%        6   1.1% Regexp#===
       5   0.9%  54.6%      209  39.2% #<Module:0x00000002cbf5a0>#translate
       5   0.9%  55.5%      282  52.9% ActiveModel::Errors#generate_message
       5   0.9%  56.5%        5   0.9% Array#concat
       5   0.9%  57.4%       47   8.8% Hash#each
       5   0.9%  58.3%        5   0.9% I18n::Config#backend
       5   0.9%  59.3%       18   3.4% Kernel#dup
       5   0.9%  60.2%       10   1.9% MonitorMixin#mon_synchronize
       4   0.8%  61.0%        6   1.1% #<Module:0x00000002cbf5a0>#config
       4   0.8%  61.7%       24   4.5% #<Module:0x00000002cbf5a0>#normalize_keys
       4   0.8%  62.5%        4   0.8% ActiveRecord::Translation#lookup_ancestors
       4   0.8%  63.2%        4   0.8% Hash#delete
       4   0.8%  64.0%        6   1.1% Hash#except!
       4   0.8%  64.7%        4   0.8% Hash#values_at
       4   0.8%  65.5%       51   9.6% I18n::Backend::Simple::Implementation#lookup
       4   0.8%  66.2%        4   0.8% Kernel#require
       4   0.8%  67.0%        4   0.8% Kernel#respond_to?
       4   0.8%  67.7%        4   0.8% String#intern
       3   0.6%  68.3%        3   0.6% #<Module:0x00000002cbf5a0>#normalized_key_cache
       3   0.6%  68.9%        6   1.1% #<Module:0x007f8a0cd5fdc0>#__temp__
       3   0.6%  69.4%       10   1.9% ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#extract_pg_identifier_from_name
       3   0.6%  70.0%       42   7.9% ActiveSupport::LogSubscriber#call
       3   0.6%  70.5%        3   0.6% Array#-
       3   0.6%  71.1%        9   1.7% Hash#merge
       3   0.6%  71.7%      123  23.1% I18n::Backend::Base#default
       3   0.6%  72.2%        8   1.5% I18n::MissingTranslation::Base#initialize
       3   0.6%  72.8%        3   0.6% IO#write
       3   0.6%  73.4%        3   0.6% Kernel#throw
       3   0.6%  73.9%      480  90.1% RSpec::Core::Example#run
       3   0.6%  74.5%        3   0.6% Regexp#initialize
       3   0.6%  75.0%        3   0.6% String#%
       3   0.6%  75.6%        7   1.3% Time#minus_with_coercion
       2   0.4%  76.0%       22   4.1% ActiveModel::Validations::UrlValidator#validate_each
       2   0.4%  76.4%       20   3.8% ActiveRecord::LogSubscriber#sql
       2   0.4%  76.7%        3   0.6% ActiveSupport::LogSubscriber#color
       2   0.4%  77.1%        2   0.4% ActiveSupport::Notifications::Fanout#listeners_for
       2   0.4%  77.5%        4   0.8% Arel::Visitors::Visitor#visit
       2   0.4%  77.9%       10   1.9% Array#collect
       2   0.4%  78.2%        2   0.4% Array#flatten!
       2   0.4%  78.6%        2   0.4% Array#hash
       2   0.4%  79.0%        2   0.4% Class#configurations
       2   0.4%  79.4%        7   1.3% Class#match
       2   0.4%  79.7%       17   3.2% Hash#except
       2   0.4%  80.1%        2   0.4% Logger::SimpleFormatter#call
       2   0.4%  80.5%        2   0.4% Marshal.dump_without_mocks
       2   0.4%  80.9%       63  11.8% Module#interpolate
       2   0.4%  81.2%      361  67.7% Prize#_run__2501234485523728663__validate__1858047214644115366__callbacks
       2   0.4%  81.6%        2   0.4% Symbol#to_s
       2   0.4%  82.0%        2   0.4% Thread#[]
       2   0.4%  82.4%        2   0.4% Time#initialize
       1   0.2%  82.6%        2   0.4% #<Module:0x00000002cbf5a0>#handle_exception
       1   0.2%  82.7%        1   0.2% ActiveModel::Errors#[]
       1   0.2%  82.9%      280  52.5% ActiveModel::Errors#add
       1   0.2%  83.1%      278  52.2% ActiveModel::Errors#normalize_message
       1   0.2%  83.3%       67  12.6% ActiveModel::Name#human
       1   0.2%  83.5%      364  68.3% ActiveModel::Validations::Callbacks#run_validations!
       1   0.2%  83.7%        8   1.5% ActiveModel::Validations::NumericalityValidator#parse_raw_value_as_a_number
       1   0.2%  83.9%      149  28.0% ActiveModel::Validations::PresenceValidator#validate
       1   0.2%  84.1%        4   0.8% ActiveRecord::Associations::JoinDependency#initialize
       1   0.2%  84.2%        5   0.9% ActiveRecord::AttributeMethods#respond_to?
       1   0.2%  84.4%        1   0.2% ActiveRecord::AttributeMethods::BeforeTypeCast#read_attribute_before_type_cast
       1   0.2%  84.6%        4   0.8% ActiveRecord::AttributeMethods::Dirty#write_attribute
       1   0.2%  84.8%        1   0.2% ActiveRecord::AttributeMethods::Write#type_cast_attribute_for_write
       1   0.2%  85.0%       62  11.6% ActiveRecord::ConnectionAdapters::AbstractAdapter#log
       1   0.2%  85.2%       69  12.9% ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#disable_referential_integrity
       1   0.2%  85.4%        1   0.2% ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#quote
       1   0.2%  85.6%        1   0.2% ActiveRecord::ConnectionAdapters::PostgreSQLColumn#type_cast_with_extended_types
       1   0.2%  85.7%        1   0.2% ActiveRecord::ExplainSubscriber#call
       1   0.2%  85.9%        1   0.2% ActiveRecord::QueryMethods#where
       1   0.2%  86.1%        1   0.2% ActiveRecord::Result#hash_rows
       1   0.2%  86.3%        1   0.2% ActiveRecord::Scoping::ClassMethods#current_scope=
       1   0.2%  86.5%        5   0.9% ActiveRecord::SpawnMethods#except
       1   0.2%  86.7%       30   5.6% 

如果需要,整個文件位於此處: https : //docs.google.com/document/d/16F38guxjBVFpu8Xp1rwK14TWREPcM3wtiLvfBGG7NB0/edit?usp=sharing

我讀了幾篇有關如何縮短時間的文章,但是我想首先了解為什么它這么慢(30分鍾!),然后才可以選擇正確的測試優化技術。

似乎大多數時候都在使用錯誤消息進行驗證。 您可以嘗試對其進行優化,但是如果您要查找的是簡單的加速,則可以將過程的整個部分都保留下來。 我只是將ActiveModel::Errors#generate_message"error message"一起存根,這樣可以節省很多處理時間。

ActiveModel::Errors.any_instance.stub(:generate_message).and_return('error message')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM