我在我的Rails应用程序中进行了一个简单的测试,该测试的持续时间比其他明显相似的测试要长得多。
运行test_invalid_without_name
需要1到2秒的实时时间,如下所示:
VALID_PARAMS = { name: 'Client record' }
def test_invalid_without_name
c = Client.new(VALID_PARAMS)
c.name = nil
refute c.valid?, 'should not be valid without a name'
end
下一个测试test_valid_with_all_params
不到1/100秒:
def test_valid_with_all_params
c = Client.new(VALID_PARAMS)
assert c.valid?, 'should be valid with appropriate parameters'
end
在此阶段,客户端模型非常简单:
class Client < ActiveRecord::Base
belongs_to :entity, polymorphic: true
validates :name, presence: true
end
任何人都可以在这里发现什么是错的,或者让我知道我应该在哪里看下去试图解决这个问题?
更新1
我使用ruby-prof来分析代码,似乎很多时候花在Psych gem上。我相信这是在ActiveRecord::..#serialize
中使用的,我在另一个模型中使用如下:
class Opportunity < ActiveRecord::Base
belongs_to :client
serialize :details, Hash
end
但是,在此处删除对serialize
的调用对客户端测试没有任何影响(我无法理解为什么会这样,这两个类是关联的,但客户端中没有实例化机会检验)。
更新2
原因是因为I18n正在使用它而被调用。我在这一点上的假设是失败的验证导致I18n转到语言环境文件以提取错误消息。我将研究I18n进行测试......
答案 0 :(得分:2)
事实证明,解决这个问题的合适方法是使用ruby-prof如下。
添加到Gemfile(在development
组中):
gem 'ruby-prof'
将测试代码包含在对分析器的调用中:
def test_invalid_without_name
RubyProf.start
cr = Client.new(VALID_PARAMS)
cr.name = nil
refute cr.valid?, 'should not be valid without a name'
result = RubyProf.stop
printer = RubyProf::CallStackPrinter.new(result)
printer.print(File.open(File.join(Rails.root, 'profile_invalid_without_name.html'), 'w'))
end
这将在您的Rails应用程序的根目录下创建一个交互式HTML文档,该文档显示时间花费的细分。
在这种情况下,在I18n中寻找翻译的是80%以上。我将以下行添加到config/environments/test.rb
以在测试中将其删除:
I18n.backend = I18n::Backend::KeyValue.new({})
我将来可能会做出以下额外改进:
更具体地说明了I18n的存根,因此全栈验收测试可以使用真实的东西。
编写更方便的分析方法。看起来ruby-prof提供了各种其他激活它的机制,这对初次使用来说是最简单的。
答案 1 :(得分:1)
如果没有更多信息,就无法回答这个问题。