tgoop.com/orgprog/411
Last Update:
Почему провалился 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 "[email protected]" 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: "[email protected]",
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
BY Организованное программирование | Кирилл Мокевнин

Share with your friend now:
tgoop.com/orgprog/411
