2012-03-08 4 views
11

Я просто добавил валидации для изображения несущей волны к модели, и теперь тесты выполняются очень медленно. Как я могу ускорить этот процесс? Я чувствую, что должен быть лучший способ.Действительно медленное тестирование с загрузкой файлов


Я работает без валидаций и используется, чтобы иметь возможность работать через мои RSpec тесты примерно 140 секунд, но так как я в настоящее время проверить наличие в :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 для тестирования установки:

CarrierWave.configure do |config| 
    config.storage = :file 
    config.enable_processing = false 
end 

ответ

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

Я бы предпочел не обходить проверки. В скрепке вы можете заполнить поле pic строкой, я надеялся на что-то подобное. –

+0

Спасибо за ответ, я понимаю, что логично, что загрузка займет больше времени, однако время загрузки слишком много для моих целей тестирования, надеясь каким-то образом минимизировать его. –

+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 
+0

Да спасибо, это уже сделано 'config.storage =: file' линия несущей волны настроить блок сил, которые, в производстве он установлен в тумане –

+0

Интересных. Тогда я не догадываюсь. Сожалею. –

+0

Ха-ха, я тоже ... –

1

Вы, наверное, считали это уже, но это 100 сек замедление, связанные с одного Загрузка файла? Если это совокупность по всем тестам, должен быть способ структурировать их, чтобы у вас был один тест (или несколько), который проверяет наличие файла, а остальное время вы просто издеваетесь над ним.

+0

Не могли бы вы предложить что-то отличное от Джефферсона Жирао или согласиться с этим? –

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% от моего набора тестов, но мой тестовый комплект тихих переменным, так что я не могу быть абсолютно уверен. Во всяком случае, просто нужно подумать о том, кто-нибудь попадает в эту проблему.

Мне не очень нравится решение, требующее от вас не проверять модель.Я думаю, это похоже на ответ StringIO Вольфрама Арнольда, хотя я думаю, что этот способ немного легче понять.

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 

Две ключевых вещи здесь:

  1. загрузка сеттеры CarrierWave может иметь смысл целой кучи вещей. Они делают это, обертывая то, что получают в CarrierWave::SanitizedFile. Одна из вещей, которые он может принять, - это хэш, как здесь.

  2. CarrierWave::SanitizedFile заботится, пустой ли файл. Я слишком долго размышлял, почему он не примет мой StringIO.new. Здесь нужно что-то там, но все равно. Я дал ему коалу.