我刚刚将一个载波图像的验证添加到模型中,现在测试运行速度非常慢。我怎样才能加快这个过程?我觉得必须有更好的方法。
我一直在运行而没有经过验证,过去能够在大约140秒内完成我的rspec测试,但是因为我现在验证了:display_pic
的存在,我必须将真实的文件上传添加到我的项目中厂。这已经增加到240秒! 140已经处于沉重的一面,这真是太疯狂了。
This is how the carrierwave github page recommends setting up Factory Girl:
FactoryGirl.define do
factory :project do
display_pic { File.open(File.join(Rails.root, 'spec', 'support', 'projects', 'display_pics', 'test.jpg')) }
end
end
我将上面的test.jpg作为一个空的文本文件,因此它本质上尽可能小。
我也遵循了载波建议来设置测试:
CarrierWave.configure do |config|
config.storage = :file
config.enable_processing = false
end
答案 0 :(得分:9)
您的上传是存储在本地还是转到像S3这样的云端服务?如果是后者,这可能会破坏你的测试表现。
对于测试,模拟任何外部依赖项总是好习惯。如果这是您的问题,您应该使用工具来模拟连接。我认为fog gem内置了对此的支持。
更新:Regarding the answer by Jefferson Girao,我使用了一个技巧来避免打开测试文件,而是使用StringIO来模拟测试文件以用于工厂目的。这样做效果更好,因为它避免了磁盘访问:
def test_file_stream(filename = 'test.jpg', mime_type='image/jpg', content = '')
StringIO.new(content).tap do |s|
s.content_type = mime_type
s.original_filename = filename
end
end
答案 1 :(得分:6)
现在验证一直在创建实例,访问属性display_pic,括号内的代码
{ File.open(File.join(Rails.root, 'spec', 'support', 'projects', 'display_pics', 'test.jpg')) }
将被执行(它被懒惰地执行)。这导致时间上的差异。
避免这种情况的一个选项是为工厂定义设置to_create我不建议:
FactoryGirl.define do
factory :project do
display_pic { File.open(File.join(Rails.root, 'spec', 'support', 'projects', 'display_pics', 'test.jpg')) }
to_create do |instance|
instance.save!(:validate => false)
end
end
end
答案 2 :(得分:3)
灵感来自@jeffersongirao和@Wolfram Arnold:
FactoryGirl.define do
sequence(:image) do |n|
{
tempfile: StringIO.new('{・㉨・}'),
filename: "#{n}.jpeg",
content_type: 'image/jpeg'
}
end
factory :user do
avatar { generate(:image) }
end
end
这里有两个关键的事情:
CarrierWave的上传设定器可以理解一大堆事物。他们通过将他们获得的内容包装在CarrierWave::SanitizedFile
中来实现。其中一件事就是哈希,就像这里一样。
CarrierWave::SanitizedFile
关心文件是否为空。我花了太长时间想知道为什么它不接受我的StringIO.new
。它需要那里有东西,但它并不关心什么。我给了它一只考拉。
答案 3 :(得分:1)
您可能已经考虑过这一点,但是与单文件上传相关的100秒减速?如果它是所有测试的聚合,那么必须有一种方法来构造它们,以便您有一个验证文件存在的单个测试(或几个),其余的时间只是模拟它。
答案 4 :(得分:1)
我刚刚遇到这个问题,它可能有助于通过将文件存储在内存中来解决它,而不是让工厂每次测试都从磁盘读取映像。我正在使用以下内容。
DUMMY_IMAGE = File.open(File.join(Rails.root, 'spec', 'support', 'projects', 'display_pics', 'test.jpg'))
FactoryGirl.define do
factory :project do
display_pic DUMMY_IMAGE
end
end
我认为我在测试套件上节省了大约10%的时间,但我的测试套件是安静的变量,所以我不能完全确定。无论如何,如果有人遇到这个问题,只需考虑一些事情。
我真的不喜欢要求您不验证模型的解决方案。我想这与Wolfram Arnold的StringIO答案相似,尽管我认为这种方式有点容易理解。