Семинар BDD: работа над ошибками

Привет.
На последней встрече DevClub 26 октября мы предприняли попытку провести семинар по BDD.
К сожалению, в практической части мы преуспели мало, поэтому попытаемся проанализировать результаты здесь.

Итак, было дано практическое задание — регистрация на девклуб:

Задание

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

  1. Имя и email обязательны.
  2. Два раза на одну встречу зарегистрироваться нельзя.
  3. Если участвовал раньше — одно подтверждение, а если впервые — то другое.
  4. После регистрации мыло попадает в общий список участников
  5. Если все места заняты, то человек добавляется в очередь
  6. Если кто-то отказывается, то регистрируется первый человек из очереди (и ему посылается подтверждение)

Попробуем здесь реализовать первые два требования с помощью BDD.
Напомню, что все здесь можно скачать минимальный необходимый набор, чтобы начать использовать BDD на своём любимом языке.

Решение №1

Итак, требование номер 1:

Имя и email обязательны.

С чего начать реализовывать это требование?
BDD, также как и TDD, учит: начинать надо с юнит-тестов, то бишь со спецификации.

На семинаре подопытный юный программист, роль которого исполнил Антон Архипов, написал первый юнит-тест на Руби примерно таким образом:

Это классическая ошибка тех, кто начинает писать юнит-тесты. Именно она приводит к таким распространённым заблуждениям, как «юнит-тесты ничего не тестируют», «юнит-тесты дублируют основной код» и т.д. Этот конкретный тест действительно ничего не тестирует: он присваивает переменной значение и в следующей же строке проверяет, что оно всё ещё не пустое. Это бессмысленно: за это время значение переменной не могло измениться; не могло ничего сломаться. Говоря терминами BDD, эта спецификация никак не описывает поведение программы. Как сделать этот тест осмысленным? Надо вызвать какое-то действие, которое может что-то сломать.

BDD как раз помогает избавиться от таких ошибок. Вспомним, в классической спецификации BDD должно быть три секции: GIVEN, WHEN, THEN. Попробуем их написать:

  • GIVEN Человек без имени
  • WHEN он пытается зарегистрироваться на встречу devclub
  • THEN система должна выдать ошибку

В первом ошибочном тесте отсутствует самая важная часть WHEN, то есть тест не производит никакого действия. Поэтому и нет поведения, которое надо было бы проверять.

Какое действие надо произвести? Читаем: «он пытается зарегистрироваться». Переводя на наш программерский язык: «Вызывает функцию register». Пробуем:

Вот теперь этот тест спецификация описывает поведение метода Devclub.register: при передаче человека без имени она должна выкинуть ошибку.

Как мы уже говорили, писать спецификации в стиле BDD можно и с помощью обычного JUnit:

Думаю, после этого написать исходный код классов Devclubber и DevclubRegistration не составит труда:


На этом требование номер один считаем реализованным. Переходим ко второму требованию.

4 комментария Семинар BDD: работа над ошибками

  1. Anton Tanasenko:

    Честно говоря в BDD немного разочаровался. Ожидал от этой аббревиатуры чего-то большего.. другой подход что-ли.
    А получились те же яйца только в профиль 🙂

    Спойлер: в юнит тесте надо первую и вторую регистрацию вынести в отдельные тесты (методы), иначе падение IllegalArgumentException при первой регистрации будет расцениваться как правильное.

    1. Наконец-таки спасибо за фидбак.
      На самом деле я специально рассказывал про БДД так, чтобы показалось похоже на ТДД — для того, чтобы девелоперам было проще понять. И мои примеры все были низкоуровневые, то есть почто что юнит-тесты. А так вообще в БДД есть больше, чем я показал, так что разочаровываться не надо, а надо попробовать и посмотреть примеры.

  2. Alexey:

    Какой недостаток решения на jUnit? Привязывание к IllegalArgumentException? Или название метода?

What do you think?

Note: Your email address will not be published

You may use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*