Почему провалился BDD?
Программирование управляемое поведением когда-то захватило умы разработчиков и об этом говорили буквально на каждом углу. Для поддержания этой идеи появился целый пласт инструментов, использовать которые было просто обязательно для любого прогрессивного разработчика. Активно пошли в мир тестовые подходы и фреймворки типа cucumber и rspec, отовсюду звучало Given-When-Then. А потом раз и все это исчезло как и появилось. Что случилось?
Идея BDD не нова, кейсы, примеры, сценарии существовали десятилетиями: Use Cases (1990-е), User Stories (начало 2000-х), Acceptance Criteria, примерно весь классический системный анализ.
BDD, по сути, внес такую формулировку:
⁃ Пример и есть требование. ⁃ Примеры и есть документация. ⁃ Примеры и есть тесты.
То есть мы один раз пишем конкретный кейс используя специальный язык (соглашения), а из него автоматически получаются все нужные артефакты. Таким образом мы сильно экономим время, требования меняются одновременно с тестами и так далее, сплошные плюсы. Вот как это выглядело:
Feature: User login
Scenario: Login fails with invalid password Given a registered user exists And I am on the login page When I enter "user@example.com" into the "Email" field And I enter "wrong-password" into the "Password" field And I click the "Login" button Then I should see "Invalid email or password" And I should remain on the login page
Читается? Да. Понимает ли это бизнес? Возможно, в первый день. Но это только верхушка айсберга. Реальная работа происходит в другом месте - в описаниях шагов, так называемых step definitions, которые нужно писать отдельно:
Given("a registered user exists") do @user = User.create!( email: "user@example.com", password: "correct-password" ) end
Given("I am on the login page") do visit "/login" end
When('I enter "{string}" into the "{string}" field') do |value, field| fill_in field, with: value end
When('I click the "{string}" button') do |button| click_button(button) end
Then('I should see "{string}"') do |text| expect(page).to have_content(text) end
Then("I should remain on the login page") do expect(page).to have_current_path("/login") end
И вот тут начинается жопа. Этот слой быстро разрастается до сотен методов (даже для простых кейсов), которые должны быть одновременно “универсальными”, “переиспользуемыми” и “человеко-читаемыми”. На практике это приводит к бесконечному количеству абстракций вида “When I click the ‘Login’ button” и “Then I should see ‘Success’”, которые не помогают ни бизнесу, ни разработчикам, ни тестировщикам. Стейкхолдеры даже не открывали эти сценарии.
Разработчикам приходилось тратить значительно больше времени, для того чтобы эти тесты писать и поддерживать. Мантра была - такие тесты проще понять, но, в реальности, мы получили еще один слой абстракции и много жарких разговоров на тему того, а как правильно все это писать. А они еще сильно завязаны на визуальную часть, что ближе к e2e тестам с точки зрения кода. Это сильно добавляет хрупкости и усложняет отладку. В какой-то момент bdd и e2e стали чуть ли не синонимами у многих команд.
BDD провалился, потому что его реальная ценность была в коммуникации, а его реальная практика стала про автоматизированные UI-тесты. Несмотря на это, в те годы родилось много инструментов, элементы которых до сих пор живут в разных экосистемах. Например те же матчеры отлично прижились в vitest/jest, в ruby мире по прежнему популярен rspec.
p.s. Хорошее видео по теме https://www.youtube.com/watch?v=Bq_oz7nCNUA
Ссылки: Телеграм | Youtube | VK
В этом посте были ссылки, но мы их удалили по правилам Сетки
· 05.12.2025
«И вот я на странице входа. Когда ввожу я почту свою в поле ”email”. И когда ввожу я неверный пароль в поле ”password”. И когда нажимаю я кнопку входа. Должен я получить ошибку “ Неверный email или пароль“. И должен я остаться на странице входа.»
Это, чёрт возьми, прекрасно! Нужно описывать бизнес требования только так!
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён