[英]Why do my rspec Rails tests on ONE model is taking 10 minutes ?! (Rails 3.2/rspec 2/Guard/spork)
I have rspec tests defined in my app but they are taking ages! 我在我的应用程序中定义了rspec测试,但是它们已经花了很多年了! In my whole app, I have 438 tests running in 37 minutes.
在我的整个应用程序中,我在37分钟内运行了438个测试。 That's only 10 tests per minute.
每分钟只有10次测试。
I use Guard for rspec, Spork so I think it should be much faster. 我将Guard用作rspec,Spork,所以我认为它应该更快。 there must be something wrong going on.
一定有什么不对劲。
For example, the rspec test on the model 'Prize' is taking 13 minutes for 134 tests. 例如,模型“ Prize”上的rspec测试需要134分钟进行13分钟的测试。 It is terribly slow!
太慢了! Here is my spec for Prize:
这是我对奖品的说明:
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
I have adjusted Garbage collector( http://makandracards.com/makandra/950-speed-up-rspec-by-deferring-garbage-collection ) but it almost had no effect. 我已经调整了垃圾收集器( 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
I use https://github.com/tmm1/perftools.rb to assess the time spent and understand why it takes so long. 我使用https://github.com/tmm1/perftools.rb来评估花费的时间并了解为什么要花费这么长时间。 Here is the analysis by perftools
这是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%
The whole file is here if necessary: https://docs.google.com/document/d/16F38guxjBVFpu8Xp1rwK14TWREPcM3wtiLvfBGG7NB0/edit?usp=sharing 如果需要,整个文件位于此处: https : //docs.google.com/document/d/16F38guxjBVFpu8Xp1rwK14TWREPcM3wtiLvfBGG7NB0/edit?usp=sharing
I read a few articles on how to improve time, but I would like first to understand why it is so slow (30 minutes!) and then I could pick the right test optimization techniques. 我读了几篇有关如何缩短时间的文章,但是我想首先了解为什么它这么慢(30分钟!),然后才可以选择正确的测试优化技术。
It seems like it's using most of the time generating the error messages for your validations. 似乎大多数时候都在使用错误消息进行验证。 You could try to optimize that, but if what you're looking for is a simple speedup, you can just stub that whole part of the process.
您可以尝试对其进行优化,但是如果您要查找的是简单的加速,则可以将过程的整个部分都保留下来。 I would just stub
ActiveModel::Errors#generate_message
with "error message"
, which should save a lot of processing time. 我只是将
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.