Действительно ли RSpec и Cucumber того стоят?

12

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

Во-первых, стоит ли проводить тестирование? Я имею в виду, стоит ли тратить время на написание тестов?

Затем я использую RSpec, я недавно открыл для себя Cucumber, использовал его некоторое время, но я не знаю, стоит ли писать все эти шаги на самом деле? Я знаю, что могу повторно использовать шаги, но я никогда не знаю, являются ли эти шаги слишком полными или нет: например, я использовал, Given I am logged in as (.+)но я не знаю, должен ли я сказать в его определении, Given there's a user called $1потому что он может дублировать пользователя, если когда-либо будет создан но не стоит всегда делать шаг раньше Given I am logged in as (.+). Это довольно много кода, который может быть редко полезным. Я думаю, что нет новых ошибок в тестируемых деталях каждый день ... Так стоит ли Cucumber по сравнению с RSpec?

Cydonia7
источник

Ответы:

13

Мой ах-ха! моменты о тестировании в Ruby и Rails наступили, когда я действительно сел и прочитал исчерпывающие ресурсы по этой теме, книги по Rspec и Cucumber . Я поделился вашим первоначальным презрением к огурцу, но потом понял, что смотрю на картинку с совершенно неправильной точки зрения.

По сути, Cucumber - это BDD (разработка, основанная на поведении) - вы используете Cucumber для планирования своих функций, над которыми вы будете работать дальше. Хм, затем вы хотите, чтобы пользователи могли продвигать посты на форуме или что-то в этом роде (чтобы украсть пример;)) Итак, вы пишете что-то простое.

Given I am logged in
And I can see the post "BDD is awesome"
When I vote the post up
Then the post should have one more vote
And the page should show a message thanking me for my vote.

Обратите внимание, что там нет ссылок на что-либо связанное с кодом. Это входит в ваши шаги. Когда вы реорганизуете свой код, вам, возможно, придется изменить определения шагов, но поведение (ваша функция) никогда не будет нуждаться в изменении.

Теперь каждый раз, когда вы запускаете свою функцию Cucumber, вы будете в значительной степени получать инструкции о том, как протестировать эту функцию с помощью TDD (разработка через тестирование). Это делается на более низком уровне с использованием RSpec.

Первый запуск - мое определение первого шага не определено. Скопируйте блок, чтобы определить его, скажем, user_steps.rb или даже session_steps.rb, поскольку он относится к пользователям и их сеансам. Теперь, как вы определяете, что пользователь вошел в систему? Вы можете принять их через процесс входа в систему.

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

Должно быть все счастливы. Второй шаг.

Given /^I can see the post "(.+)"$/ do |name|
  visit post_path(Post.find_by_name(name))
end

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

When /^I vote the post up$/ do
  pending 
end 

Здесь вы начинаете говорить о новой функциональности, но пока не знаете, как она будет работать. Как вы голосуете за пост? Вы можете щелкнуть изображение +1 или чего-то еще, что делает запись ajax контроллеру, который возвращает JSON, или что-то подобное. Так что теперь вы можете перейти к чистому тестированию Rspec.

  • Проверьте свой вид, чтобы убедиться, что изображение +1 отображается,
  • Проверьте свой контроллер на правильность работы, когда он получает заданный ajax-запрос правильного формата (как счастливый, так и несчастный путь - что, если получен недопустимый идентификатор сообщения? Что произойдет, если пользователь израсходовал 25 своих голосов за день? Правильно ли увеличивается число голосов?)
  • Проверьте ваш javascript на правильность ответа, когда ему предоставлен BLOB-объект JSON в правильном формате (обновляет ли он изображение +1, чтобы показать, что он был использован? )

Все это не влияет на поведение - но когда вы закончите работу с тестированием более низкого уровня, заполнить определение шага, как проголосовать за публикацию, будет тривиально. Это может быть так же просто, как click_link '+1'. А остальные шаги - это результаты тестирования, которые опять же должны быть простыми. И когда вы закончите, то вы знаете, что ваша функция завершена и завершена. Если необходимое поведение изменяется, вы можете настроить свою функцию, иначе вы можете настроить свой код реализации в полной безопасности.

Я надеюсь это имеет смысл. Все это было не в моей голове, но я думаю, что это демонстрирует разницу между BDD и TDD, и почему Cucumber и RSpec удовлетворяют различные потребности.

sevenseacat
источник
Это было действительно полезно для меня. Но у меня есть еще один вопрос: я начал проект с использованием RSpec для тестирования контроллеров и представлений, код на 90% покрыт тестами. Как вы думаете, мне действительно нужен огурец и сейчас я трачу время на написание шагов и сценариев? Я имею в виду, я могу сделать все это с RSpec в любом случае.
Cydonia7
@Skydreamer: Возможно, нет необходимости, но это может быть хорошей практикой. Пока вы проводите тестирование, вы на правильном пути :)
sevenseacat
10

Тестирование, на мой взгляд, это искусство. При использовании TDD (с использованием RSpec или любой другой среды) изначально создается ощущение, что вы «тратите свое время». Это понятно, потому что вы не пишете никакого производственного кода.

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

Кроме того, наличие тестов может быть полезным для проверки кода, поскольку ваш рецензент может видеть, какие сценарии вы тестируете и как ваш код предназначен для использования.

Как только вы попадаете в топ TDD, делать что-то еще - это неправильно.

Дэвид Вайзер
источник
2
+1, хотя, исходя из опыта, «попасть в раскачку TDD» само по себе является геркулесовским усилием и очень трудным для большинства разработчиков.
Уэйн Молина
@ Уэйн М: Согласен. Попасть в TDD-паз сложно, но преимущества огромны. :)
Дэвид Вайзер
Трудно сказать это легко ... годами пытался обдумать это :)
Уэйн Молина
Ах, да, это того стоит.
sevenseacat
2

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

Модульные тесты и регулярные интеграционные тесты, выполняемые либо с помощью Rspec, либо Test :: Unit, имеют большой смысл, но, к счастью, они гораздо быстрее пишутся, чем тесты Cucumber. Например, вы можете использовать чистый Ruby вместо того, чтобы бороться с многословным и неловким синтаксисом Gherkin.

Джек Кинселла
источник
2
Я могу с уверенностью сказать, что я не согласен с каждым из ваших пунктов о тестировании огурца. * Это не нарушает хорошие текстовые редакторы (мой gedit выделит и автоматически завершит его просто отлично), * Вы не должны копировать какие-либо тестовые настройки из вашей существующей настройки Rspec в вашу настройку Cucumber (два набора тестов запускаются на совершенно разных уровнях детализации), * если вы не можете быть последовательными в названии своих страниц, это не ошибка Cucumber (Rails не позволяет вам называть маршруты разными вещами в разные дни, так почему Cucumber?) (продолжение следует)
sevenseacat
1
* Вы говорите, что такое соглашение о пошаговых файлах, но потом говорите, что не знаете, где искать, чтобы следовать соглашению? Почему продвижение поста должно быть чем-то другим, кроме post_steps.rb? * Ваши функции не должны быть кодом, поэтому многословность не имеет значения - ваши функции - документация о том, как ваше приложение ведет себя; И, наконец, я могу критиковать «не поощряя повторное использование кода», если вы делаете это неправильно .
sevenseacat
2

Во что я лично верю, так это RSpec testing is a definite must. Скажем, например, что вы хотите написать новую функцию, которая также имеет ссылку на какую-то другую функцию, и на эту функцию может ссылаться другой модуль или методы. Итак, как вы можете убедиться, что то, что вы пишете, не нарушает любую другую часть приложения?

Предположим, что у вас большое приложение и что вы написали что-то тривиальное по сравнению с общим приложением, будете ли вы повторно тестировать все приложение, нажимая каждую ссылку в приложении, чтобы убедиться, что оно работает каждый раз, когда вы меняете одну строку кода?

Тем не менее, я считаю, что тестирование на огурец не является обязательным. Я думаю, что интеграционное тестирование с использованием самого RSpec имеет больше смысла до тех пор, пока ваш клиент не проверит тесты. Который по моему опыту редкий. Если ваша команда целиком состоит из разработчиков, то я думаю, что вам лучше заменить этапы Cucumber для тестирования функций RSpec. И я думаю, что после RSpec 3 DSL тесты в значительной степени читабельны.

Пример:

Определение шага огурца:

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

Функциональный тест RSpec:

feature 'Given the user is logged in' do
      visit login_path
      fill_in :name, :with => 'Joe'
      fill_in :password, :with => 'Password'
      click_link_or_button 'submit'
end

Я думаю, что вместо того, чтобы иметь функции Cucumber, функции RSpec делают то же самое без лишней головной боли написания других определений шагов.

Кроме этого это также чисто ваши собственные предпочтения.

Надеюсь, это поможет вам немного понять.

Санкалп Сингха
источник
0

На мой взгляд, первое, что нужно дифференцировать между практикой и конкретными рамками. Огурец его не BDD, RSpec его не TDD.

Если вы хотите протестировать свою систему RSpec, это хороший инструмент, вы можете сделать TDD или BDD с RSpec, фактически TDD и BDD - это одно и то же. Кто-то говорит: «BDD - это TDD, сделанный правильно», и я полностью согласен с этим, BDD в первую очередь касается тестирования функций / поведения, а не методов / классов тестирования. На самом деле TDD, который Кент Бек описывает, об особенностях, но BDD помогает многим людям понять это ключевое отличие и его большой вклад от Дана Норта в сообщество разработчиков.

Используйте Cucumber, если считаете, что вам нужен лучший инструмент для общения с деловыми людьми, например, если Cucumber позволяет, чтобы ваши деловые люди или владелец продукта помогали команде в написании или пересмотре сценариев. Другим людям нравится cucumber, потому что эти сценарии - действительно хорошая документация системы, если вы чувствуете, что вам нужна документация такого типа, попробуйте cucumber.

В итоге:

  • Если вы хотите сделать TDD / BDD самостоятельно или своей командой -> попробуйте RSpec
  • Если вы хотите лучший способ общения с бизнесом с помощью пользовательских историй и сценариев -> попробуйте огурец
  • Если вам нужна документация по функциям вашей системы -> попробуйте огурец.

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

Но всегда помните, что RSpec и Cucumber - это всего лишь инструменты, а инструменты решают конкретные проблемы, какую проблему вы хотите решить? Задайте себе этот вопрос, и вы, вероятно, в лучшем положении, чтобы выбрать правильный инструмент. Быть лучшим программистом - это принимать решения, а не использовать X или Y framework / tool / library / technology.

AlfredoCasado
источник