Все курсы
Акции и промокоды Отзывы о школах

Behavior-Driven Development: что это и как использовать в разработке

Знаете, что общего между разработчиками и заказчиками? Правильно — они часто говорят на разных языках (и я сейчас не про Java и английский). В то время как бизнес мыслит пользовательскими сценариями и бизнес-ценностью, разработчики погружены в мир кода, тестов и технических спецификаций. И вот тут-то на сцену выходит BDD — Behavior-Driven Development, или, если по-нашему, «разработка через поведение».

Behavior-Driven Development (BDD)

BDD как формализованный подход появился в период между 2003 и 2006 годами, когда Дэн Норт (Dan North) — человек, глубоко погруженный в практики разработки через тестирование (TDD) и доменно-ориентированное проектирование (DDD) — систематизировал и развил эти идеи для решения проблемы недопонимания между бизнесом и разработкой. Опираясь на существующие подходы TDD и DDD, он сформулировал принципы и практики BDD, создав методологию, которая наконец-то позволила всем участникам процесса говорить на одном языке.

Суть BDD проста, как и всё гениальное: давайте описывать поведение системы так, чтобы это понимали все участники процесса — от генерального директора до джуниор-разработчика (ну, может быть, кроме котика тимлида, но он обычно и так всем доволен). Причём описывать не в стиле «система должна обеспечивать персистентность данных через реляционную модель», а по-человечески: «когда пользователь нажимает кнопку ‘Сохранить’, его данные сохраняются в системе».

В общем, если вы когда-нибудь играли в испорченный телефон на встречах с заказчиком, то BDD — это как раз то, что доктор прописал. Только вместо таблеток — понятные всем сценарии поведения системы.

Преимущества BDD

А теперь давайте поговорим о том, почему BDD — это не просто очередная модная аббревиатура в мире IT (которых, признаться, у нас и так хватает).

Во-первых — и это, пожалуй, главное — BDD решает извечную проблему «испорченного телефона» в команде. Знаете эту ситуацию, когда заказчик хочет кнопку «купить», разработчик делает полноценную платежную систему, а тестировщик проверяет работу корзины? С BDD такие казусы случаются значительно реже (хотя, конечно, полностью от них не застрахован никто — мы же люди, в конце концов).

Второе преимущество — это то, что ваша документация наконец-то начинает приносить реальную пользу (да-да, я знаю, звучит как фантастика). Поскольку описания поведения системы становятся исполняемыми тестами, документация всегда актуальна. Нет больше этих душераздирающих моментов, когда вы открываете документацию двухлетней давности и понимаете, что она описывает совершенно другую систему.

И наконец — что особенно оценят менеджеры проектов — BDD позволяет начинать тестирование еще до того, как написана первая строчка кода. Тестировщики могут писать автотесты, основываясь на согласованных сценариях, параллельно с разработкой. Это как купить билеты на поезд заранее, а не стоять в очереди в кассу за 5 минут до отправления.

А еще (и это мой личный фаворит) BDD помогает избежать ситуации «а мы думали, что это будет работать по-другому» на демо у заказчика. Потому что все сценарии поведения системы согласованы заранее, записаны человеческим языком и подтверждены автотестами. Красота!

Основные компоненты BDD

Роль Gherkin в BDD

А теперь давайте поговорим о настоящей звезде BDD-подхода — языке Gherkin. Если BDD — это способ мышления, то Gherkin — это его язык. И знаете что? Это, пожалуй, единственный язык программирования, который даже ваша бабушка сможет прочитать (если, конечно, она не была ведущим разработчиком в IBM).

Gherkin использует простые ключевые слова, которые знакомы любому, кто хоть раз пытался объяснить что-то по шагам: Given (Дано), When (Когда), Then (Тогда). Это как рецепт приготовления борща, только вместо «нарежьте свеклу кубиками» у нас «пользователь вводит логин и пароль».

Выглядит это примерно так:

Feature: Авторизация пользователя
  Scenario: Успешный вход в систему
	Given пользователь находится на странице логина
	When пользователь вводит корректные учетные данные
	And нажимает кнопку "Войти"
	Then система авторизует пользователя
	And перенаправляет его на главную страницу

Заметьте, никаких тебе «инкапсуляций», «полиморфизмов» и прочих страшных слов, от которых у менеджеров начинается нервный тик. Всё просто и понятно, как в детской книжке (только без картинок, извините).

И самое прекрасное в Gherkin — это то, что под этим человекопонятным описанием скрывается настоящий исполняемый код. То есть компьютер тоже его понимает (что иногда кажется настоящим чудом, особенно после очередного релиза). Это как если бы вы могли написать техническое задание, которое само себя проверяет — мечта любого менеджера проекта!

Реализация Gherkin для различных фреймворков

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

Давайте посмотрим, как один и тот же сценарий Gherkin может быть реализован в разных фреймворках (спойлер: это не так страшно, как может показаться на первый взгляд).

Возьмем наш любимый пример с авторизацией:

Feature: Авторизация пользователя
Scenario: Успешный вход в систему
  Given пользователь находится на странице логина
  When пользователь вводит корректные учетные данные
  Then система авторизует пользователя

Java + Cucumber

Для Java-разработчиков это будет выглядеть примерно так:

public class LoginStepDefinitions {
    @Given("пользователь находится на странице логина")
    public void userIsOnLoginPage() {
        loginPage.navigate();
    }
    
    @When("пользователь вводит корректные учетные данные")
    public void userEntersValidCredentials() {
        loginPage.enterCredentials("user", "password");
        loginPage.clickLogin();
    }
    
    @Then("система авторизует пользователя")
    public void systemAuthenticatesUser() {
        assertTrue(homePage.isUserLoggedIn());
    }
}

Python + Behave

А вот как это же самое будет выглядеть для Python-энтузиастов:

@given('пользователь находится на странице логина')
def step_impl(context):
    context.browser.get(login_page_url)

@when('пользователь вводит корректные учетные данные')
def step_impl(context):
    context.browser.find_element_by_id('username').send_keys('user')
    context.browser.find_element_by_id('password').send_keys('password')
    context.browser.find_element_by_id('login-button').click()

@then('система авторизует пользователя')
def step_impl(context):
    assert context.browser.current_url == home_page_url

JavaScript + Jest-Cucumber

Ну и для любителей JavaScript (куда же без него):

import { Given, When, Then } from 'jest-cucumber';

Given('пользователь находится на странице логина', async () => {
    await page.goto(loginPageUrl);
});

When('пользователь вводит корректные учетные данные', async () => {
    await page.fill('#username', 'user');
    await page.fill('#password', 'password');
    await page.click('#login-button');
});

Then('система авторизует пользователя', async () => {
    expect(await page.url()).toBe(homePageUrl);
});

Заметили что-то интересное? Правильно — несмотря на разные языки и фреймворки, структура кода остается похожей. Это одно из главных преимуществ Gherkin: один сценарий может быть легко реализован на любом языке программирования. Это как универсальный пульт, который подходит к любому телевизору (ну, почти к любому).

Важный момент: независимо от выбранного фреймворка, старайтесь придерживаться принципа DRY (Don’t Repeat Yourself). Создавайте переиспользуемые шаги, особенно для часто повторяющихся действий вроде авторизации или проверки сообщений об ошибках. Это сэкономит вам кучу времени в долгосрочной перспективе (и нервов тоже).

А теперь, когда мы разобрались с тем, как Gherkin работает в разных фреймворках, давайте посмотрим на инструменты, которые помогут нам все это реализовать на практике…

Инструменты для BDD

Знаете, как говорят: хороший инструмент — половина работы. В случае с BDD это особенно актуально, потому что без правильных инструментов весь этот прекрасный Gherkin рискует остаться просто набором текстовых файлов где-нибудь в недрах вашего репозитория.

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

Следом идет SpecFlow — это как Cucumber, только для тех, кто не мыслит свою жизнь без .NET (да, такие люди существуют, и им тоже нужен BDD). А для любителей Python есть Behave — простой и элегантный, как сам Python (только без пробелов вместо табуляции, слава богу).

JBehave — это мощный инструмент для Java-разработчиков, который, несмотря на enterprise-направленность, предлагает современный подход к конфигурации через аннотации и поддержку Groovy. Благодаря этому написание и поддержка тестов становятся более простыми и понятными.

Диаграмма, показывающая распределение популярности инструментов BDD

Выбор инструмента во многом зависит от вашего стека технологий и, что уж греха таить, от бюджета проекта (потому что некоторые инструменты стоят как подержанный автомобиль). Но главное помнить — инструмент должен помогать, а не создавать дополнительные проблемы. Если вы тратите больше времени на борьбу с инструментом, чем на написание тестов — возможно, пора поискать что-то другое.

Примеры и кейсы использования BDD

Давайте перейдем от теории к практике и посмотрим, как это всё работает в реальной жизни. Я специально выбрал максимально жизненный пример — систему денежных переводов (потому что деньги любят все, даже программисты).

Представим, что нам нужно реализовать функционал денежного перевода. Вот как это будет выглядеть в BDD-стиле:

Feature: Денежные переводы
  Scenario: Успешный перевод средств
	Given пользователь авторизован в системе
	And баланс счета составляет 150 у.е.
	When пользователь выбирает получателя с номером счета 124233
	And вводит сумму перевода 100 у.е.
	Then система рассчитывает комиссию 10 у.е.
	And общая сумма операции составляет 110 у.е.
	And после подтверждения транзакция появляется в журнале операций

А теперь самое интересное — давайте посмотрим на альтернативные сценарии (потому что в реальной жизни всё идет не по плану чаще, чем нам хотелось бы):

Scenario: Недостаточно средств
	Given пользователь авторизован в системе
	And баланс счета составляет 50 у.е.
	When пользователь пытается перевести 100 у.е.
	Then система показывает сообщение "Недостаточно средств"
	And транзакция не проводится

И вот тут начинается самое интересное. Эти сценарии — не просто текст, они становятся живыми тестами. За каждым шагом скрывается реальный код (который, признаюсь честно, выглядит не так элегантно, как Gherkin):

When('пользователь вводит сумму перевода {int} у.е.', function (amount) {
	transferPage.enterAmount(amount);
});

Then('система показывает сообщение {string}', function (message) {
	assert.equal(transferPage.getErrorMessage(), message);
});

И знаете, что самое приятное? Когда какой-нибудь особо креативный разработчик решит «оптимизировать» код и случайно сломает логику — тесты сразу об этом сообщат. Причем сообщат так, что даже менеджер проекта поймет, что пошло не так (что само по себе уже достижение).

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

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

Заключение

Что ж, давайте подведем итоги нашего путешествия в мир BDD. Знаете, это как с изучением иностранного языка — поначалу кажется сложным и неестественным, но как только начинаешь на нем думать, мир становится совершенно другим.

BDD — это не просто набор инструментов или методология разработки. Это, если хотите, новая философия создания программного обеспечения, где главное — не код сам по себе, а его соответствие реальным потребностям бизнеса. И, как любая хорошая философия, она требует определенной дисциплины и последовательности в применении.

Конечно, BDD — не серебряная пуля (которых, как мы знаем, в программировании не существует). Но это отличный способ наладить коммуникацию между всеми участниками процесса разработки и убедиться, что мы все говорим об одном и том же, когда обсуждаем функциональность системы.

Если вас заинтересовала тема BDD и вы хотите углубить свои знания в области архитектуры программного обеспечения, обратите внимание на подборку профессиональных курсов для архитекторов ПО на KursHub. Там вы найдете образовательные программы, которые помогут вам освоить не только BDD, но и другие современные подходы к проектированию и разработке программных систем.

И помните: даже самый сложный проект начинается с простого сценария Given-When-Then. Главное — сделать первый шаг. А дальше… дальше вы уже не захотите работать по-другому.

Дата: 12 января 2025
Читайте также
Блог
1 декабря 2024
Почему Python — отличный выбор для разработки игр

Python открывает двери в игровой мир для всех. Узнайте, как выбрать библиотеку, разработать свою первую игру и избежать распространённых ошибок.

Блог
10 декабря 2024
Тестирование и DevOps: автоматизация, инструменты и перспективы

DevOps преобразил мир тестирования, сделав автоматизацию и интеграцию ключевыми элементами процесса. В статье вы узнаете, как использовать инструменты вроде Jenkins, Docker и GitLab CI для создания эффективной среды тестирования, а также рассмотрите роль непрерывного тестирования в современных разработках.

Блог
2 декабря 2024
Верстальщик или дизайнер: что выбрать?

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

Блог
19 ноября 2024
iOS против Android: что выбрать для успешного старта разработки?

Какие особенности отличают разработку под iOS и Android? Узнайте, чем платформы уникальны, какие навыки понадобятся и как выбрать оптимальный путь.

Блог
10 декабря 2024
Сертификация тестировщиков: обзор возможностей и рекомендаций

Сертификация тестировщиков становится всё более значимой в IT-индустрии. В статье вы узнаете о популярных программах, таких как ISTQB и CMST, их уровнях и особенностях, а также о том, как выбрать подходящий сертификат для профессионального роста.

Блог
22 ноября 2024
Почему Selenium и Java — лучший дуэт для автоматизации тестирования?

Автоматизация тестирования требует надежных инструментов. Узнайте, как Selenium с Java помогает создавать эффективные автотесты и какие ошибки стоит избегать.

Блог
15 января 2025
Полное руководство по этапам создания анимационного ролика

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

Блог
20 января 2025
IGTV: всё, что нужно знать о платформе для видео

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

Блог
25 ноября 2024
Java vs C#: какой язык выбрать для вашего проекта?

Java и C# — лидеры в мире программирования. Мы сравним их по ключевым критериям, от синтаксиса до производительности, чтобы вы смогли выбрать оптимальный язык для своих задач.

Категории курсов
Отзывы о школах