Привет.
На последней встрече DevClub 26 октября мы предприняли попытку провести семинар по BDD.
К сожалению, в практической части мы преуспели мало, поэтому попытаемся проанализировать результаты здесь.
Итак, было дано практическое задание — регистрация на девклуб:
Задание
Каждый, кто хочет прийти на очередную встречу devclub, должен предварительно зарегистрироваться на сайте, ибо помещение рассчитано всего лишь на 80 человек. Эта регистрация сейчас делается модератором вручную, и мы хотим её автоматизировать. Требования к регистрации участников:
- Имя и email обязательны.
- Два раза на одну встречу зарегистрироваться нельзя.
- Если участвовал раньше — одно подтверждение, а если впервые — то другое.
- После регистрации мыло попадает в общий список участников
- Если все места заняты, то человек добавляется в очередь
- Если кто-то отказывается, то регистрируется первый человек из очереди (и ему посылается подтверждение)
Попробуем здесь реализовать первые два требования с помощью 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 не составит труда:
На этом требование номер один считаем реализованным. Переходим ко второму требованию.
Страницы: 12
Anton Tanasenko
Честно говоря в BDD немного разочаровался. Ожидал от этой аббревиатуры чего-то большего.. другой подход что-ли.
А получились те же яйца только в профиль 🙂
Спойлер: в юнит тесте надо первую и вторую регистрацию вынести в отдельные тесты (методы), иначе падение IllegalArgumentException при первой регистрации будет расцениваться как правильное.
Andrei Solntsev
Наконец-таки спасибо за фидбак.
На самом деле я специально рассказывал про БДД так, чтобы показалось похоже на ТДД — для того, чтобы девелоперам было проще понять. И мои примеры все были низкоуровневые, то есть почто что юнит-тесты. А так вообще в БДД есть больше, чем я показал, так что разочаровываться не надо, а надо попробовать и посмотреть примеры.
djekk
lentjaichegi
Alexey
Какой недостаток решения на jUnit? Привязывание к IllegalArgumentException? Или название метода?