Мой доклад про acceptance-тесты с kiev.rb #1
7 марта в Киеве произошла (довольно спонтанно) конференция kiev.rb, устроенная рубистами из Питера, на которой я (довольно спонтанно) читал доклад про acceptance-тесты с использованием RSpec и Capybara.
Сомневаюсь, что кто-то записывал это на видео, но, по крайней мере, вот слайды:
Системное тестирование приложений на Ruby on Rails с использованием RSpec и Capybara
Во время презентации возник вопрос, на который ответить немедленно не удалось.
Почему я каждый раз для каждого теста вызываю метод login, а не стаблю, к примеру, current_user?
Оказалось, что пример, который я выбрал для презентации, весьма наглядно показывает, почему так делать нельзя.
scenario "Preserving favorites across sessions" do
add_ad_to_favorites(@ad)
login(user)
reset_session
visit favorites_page
we.should_not see @ad.title
login(user)
visit favorites_page
we.should see @ad.title
end
Данный сценарий описывает вот что:
- Когда пользователь добавляет объявление в избранное, оно сохраняется в сессию
- При логине текущее избранное увековечивается в базе, чтобы пользователь увидел его и при следующем сеансе работы.
Итак, работа данного сценария зависит от, грубо говоря, хуков, повешенных на авторизацию.
(Да, разумеется, ты можешь сказать, что таких хуков нет и поэтому в твоем случае логин можно застабить. Но где гарантия, что так будет всегда и тесты не потеряют свою правильность?)
Правильно ли было бы проверять эти хуки в тестах логина? С точки зрения acceptance-тестирования – нет. Они не имеют отношения к возможности авторизации как таковой. Acceptance-тесты проверяют не модули кода, а сценарии взаимодействия пользователя с сайтом.
Это приводит меня к следующему моменту:
В acceptance-тестах мокать можно только те места, которые ведут себя непредсказуемо
Таких мест по большому счету два:
Запросы на внешние сервера
Всяческие API , внешние авторизации и т.п. Нельзя полагаться на их постоянную доступность и отсутствие ошибок.
(Разумеется, если совесть не позволяет не тестировать работу с внешними API, что вполне адекватно, то их нужно тестировать посредством соответствующих юнит-тестов.)
Случайные события
Если ты тестируешь какую-нибудь лотерею, само собой, придется заткнуть генератор случайных чисел.
Вопросы? Предложения?
Рад буду послушать и ответить.

Ну просто совсем не согласен с тем, что тестировать нужно «контроллеры». Если ты хочешь тестировать контроллеры, то spec/controllers + integrate_views – это то, что тебе надо. С точки зрения acceptance-тестирования – нужно тестировать сценарии поведения пользователя вне зависимости от внутренней структуры приложения и того, как эти сценарии мапятся на контроллеры.
PS. Твой тест с «Preserving favorites across sessions» содержит код с разных уровней, а именно:
login(user)reset_sessionЕсли написал login – пиши уже logout. Как пользователь будет делать reset_session?
1) Как можно тестировать только контроллеры, если задействуется модель? В слайдах не написано, но я имел ввиду, что пока контроллеры не покрыты на 100%, acceptance-тесты наверняка покрывают не весь сайт, поэтому на них можно ориентироваться.
В идеальном случае у тебя уже есть готовый список сценариев, и их остается только закодить.
2) Пользователь может сделать reset_session. :) Наиболее простой способ – он может зайти с другого компьютера. В тесте имеется ввиду именно такого рода сброс сессии.
Вполне доволен связкой Cucumber + Capybara + RSpec, да Cucumber дополнительный слой, но таким образом в работу можно вовлечь клиента и иметь какую то документацию
интересно, а Ваши клиенты действительно сами пишут stories на cucumber?… Или
это всё-таки делают разработчики? https://github.com/cavalle/steak
На данный момент уже использую Steak вместо Cucumber :)
Розовые очки сняты, выбор в пользу скорости :)
spinach кто пробовал?