home

rspec + spin (+ vim) = удобное тестирование

24 Apr 2012

Недостатки связки spork + guard

Однажды я оказался на проекте, где TDD и BDD использовали по-настоящему, а прохождение всех тестов занимало порядка 10-15 минут. Так как мы использовали guard, при сохранении теста запускались все имеющиеся тесты. Учитывая, что на проекте много интеграционных тестов, запуск тестов постоянно выдавал «всплывающие» окна браузеров с «магически» заполняемыми полями форм и ощутимое снижение производительности машины.

Казалось бы, есть хорошо известный способ устранить эту проблему: всего лишь надо в описании теста дописать :focus => true, и количество бегущих тестов сильно сократится. Но, к сожалению, я и коллеги часто забываем об этих метках. И в то время, когда должны работать только «свои» помеченные тесты, параллельно с ними бежит еще 5-6(10-12)…
Также в .rspec файле можно дописать --fail-fast, чтобы прогон тестов прекратился при первой ошибке. Тем не менее, все это – «halfass» решения, как выражаются англоязычные коллеги.

Коллега Андрей Огневский предложил еще одно решение «проблемы прогона 1000 спеков» — добавить в Guardfile следующие настройки:

:all_after_pass => false
:all_on_start => false

После такой настройки guard возникает вопрос: в чем же тогда смысл guard, если мы отключили одну из основных его функций?

Еще одним неудобным моментом стало наличие spork на проекте. Всем хорош этот drb-сервер, но иногда он виснет мертвым процессом. Покуда это выяснится, пройдет некоторое (ощутимое) количество времени, за которое вы пересмотрите весь свой проект с мыслью: «Почему же не применяются мои правки?!»

Существует достаточно радикальный способ: создать себе CI сервер. Это решение имеет один существенный недостаток для разработчика: при небольших измененях, когда вы уверены в том, что новый код не затронул всю сьюиту тестов приложения, придется ждать окончания прогона всех тестов.

Итого, в чем недостаток всех этих решений:
1. Необходимость дополнительной настройки окружения.
2. Необходимость создания дополнительного окружения (CI-сервер).
3. Большая нагрузка на рабочую машину прогоном всех тестов.
4. Необходимость следить за своими и чужими метками :focus => true.
5. Большое количество времени (пропорционально количеству тестов) на проверку работоспособности созданного теста/кода.

spin

Spin – разработка Jesse Storimer. Это такой же предзагрузчик rails-окружения, как и spork, но с кардинально другой механикой работы. Суть spin заключается в двух коммандах: spin serve и spin push. Первая загружает rails-окружение, вторая подбрасывает и запускает тесты в этом окружении. Причем, чтобы прогнать только что завершившийся прогон тестов еще раз, надо нажать Ctrl+\. Чтобы прогнать вообще все спеки на проекте — spin push spec. Это все, что нужно знать об этой утилите. Просто и со вкусом.

Контекстный запуск тестов в rspec (и spin)

В RSpec есть очень удобная вещь: можно запустить тест, отталкиваясь от строчки, на которой находится курсор. К примеру, имеем такой спек-файл:

describe Clazz do
  subject { clothes }

  context 'when it is rains' do
    it { should == [:raincoat, :umbrella] }
  end

  context 'when sun is shining' do
    it { should == [:t-shirt, :sunglasses] }
  end
end

Допустим, надо прогнать тест в контексте «when sun is shining». Для этого достаточно написать в консоли rspec <file_path>:10. Очень удобная вещь!

21 мая Jesse добавил немного моего кода в проект, и теперь, начиная с версии 0.4.6 описанный функционал из rspec доступен и в spin!

Организуем работу со spin в vim

Я делаю свою работу с его, vim’а, помощью. В этом разделе показан конфиг, который позволит запускать нужный тест двумя нажатиями клавиш.

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Spin spec pusher
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! PushToSpin(args)
  let cmd = ":! spin push %" . a:args
  execute cmd
endfunction

" Mappings
" run one rspec example or describe block based on cursor position
map !p :call PushToSpin(":" . <C-r>=line('.')<CR>)

" run full rspec file
map !P :call PushToSpin("")
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" end of the spin spec pusher
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Как это использовать? Если надо, чтобы тест выполнился в контексте нахождения курсора, набираем в режиме просмотра !p. Файл надо отправить в spin целиком – !P.

Эта и другие настройки для vim доступны здесь

Удач!

blog comments powered by Disqus