The post has been translated automatically. Original language: Russian
This is the sixth installment in a series about BDD. In the fifth part, "End-to-end example: from idea to green test," we went through the entire cycle on one function. In the seventh, "Typical mistakes and Antipatterns," we'll look at where teams most often make mistakes.
A common problem with BDD is that scripts start running through the interface, the run grows to an hour, and tests crash for random reasons. It helps to have a clear understanding of what level to check.
The test pyramid
The concept of the test pyramid was popularized by Mike Con. The meaning is simple: the higher the level, the slower and more fragile the tests are, so there should be fewer of them.
| Level | Speed | Stability | What checks | How much |
| Unit tests | Very fast | High | Individual functions and classes | Many |
| Service layer and API | Quickly | Good | Rules and component interactions | Moderately |
| UI (end-to-end) | Gradually | Low | That everything is put together and working together | Few |
Where does BDD live
BDD does not belong to any one level. This is a way to describe behavior, and scripts can be run at different levels. Rule of thumb: run the script at the lowest level, where the rule is still expressed without loss of meaning.
Using the example of booking a meeting room:
• Unit Test (TDD). Checks the interval intersection calculation function for dozens of combinations, including edge ones. The developer is reading it.
• BDD is a scenario on the service layer. "Overlapping time cannot be booked." Checks the business rule, not the details of the algorithm. The whole team reads it.
• One end-to-end scenario through the UI. "Employee opens the form, selects the time and sees the confirmation." Verifies that the interface, API, and database are assembled correctly.
The intersection rule is checked at different levels in different ways: it is complete at the unit level, as a business rule at the service level, and it is not checked at all through the interface. It is enough that a happy path has been passed through the interface once.
How to split the runs using tags
You can tag Gherkin to run different groups of scripts at different times.:
@smoke
Scenario: Free time can be booked
...
@ui @slow
Scenario: An employee books a room through a form
...Fast scripts are run on each commit, marked with @ui and @slow in a separate stage or at night.
The inverted pyramid
A typical mistake: most of the checks are written through the UI, but there are almost no unit tests. This painting is called the "ice cream cone." The run is long, the tests are fragile, and you have to look for the cause of the crash in the browser. BDD has nothing to do with it: the problem is choosing the level.
How to choose a level
Ask three questions:
1. Is it possible to check this rule without an interface? If so, check without it.
2. Do businesses need to read this? If so, write a script on Gherkin. If not, the unit test is enough.
3. What will break if the rule is broken? The higher the cost of the error, the more important it is to duplicate the check at the second level.
Result
BDD and the test pyramid complement each other: BDD answers the question of what to test and in what language to describe, and the pyramid tells you where to run it. In the seventh part, "Typical Mistakes and Antipatterns," we'll look at what goes wrong when these principles are not followed.
At what level do you have the most tests right now? Does your painting look like a pyramid?
Это шестая часть серии о BDD. В пятой части, «Сквозной пример: от идеи до зелёного теста», мы прошли весь цикл на одной функции. В седьмой, «Типичные ошибки и антипаттерны», разберём, где команды чаще всего ошибаются.
Частая проблема с BDD: сценарии начинают запускать через интерфейс, прогон растёт до часа, а тесты падают по случайным причинам. Помогает ясное понимание того, на каком уровне что проверять.
Тестовая пирамида
Концепцию тестовой пирамиды популяризировал Майк Кон. Смысл простой: чем выше уровень, тем медленнее и хрупче тесты, поэтому их должно быть меньше.
| Уровень | Скорость | Стабильность | Что проверяет | Сколько |
| Юнит-тесты | Очень быстро | Высокая | Отдельные функции и классы | Много |
| Сервисный слой и API | Быстро | Хорошая | Правила и взаимодействие компонентов | Умеренно |
| UI (сквозные) | Медленно | Низкая | Что всё собрано и работает вместе | Мало |
Где живёт BDD
BDD не относится к какому-то одному уровню. Это способ описывать поведение, а запускать сценарии можно на разных уровнях. Практическое правило: запускайте сценарий на самом низком уровне, где правило ещё выражается без потери смысла.
На примере бронирования переговорной:
• Юнит-тест (TDD). Проверяет функцию расчёта пересечения интервалов на десятках комбинаций, включая краевые. Читает разработчик.
• BDD-сценарий на сервисном слое. «Пересекающееся время забронировать нельзя». Проверяет бизнес-правило, а не детали алгоритма. Читает вся команда.
• Один сквозной сценарий через UI. «Сотрудник открывает форму, выбирает время и видит подтверждение». Проверяет, что интерфейс, API и база данных собраны правильно.
Правило про пересечение проверяется на разных уровнях по-разному: на юнит-уровне полно, на сервисном как бизнес-правило, а через интерфейс не проверяется вообще. Достаточно, что через интерфейс один раз пройден счастливый путь.
Как разделить прогоны с помощью тегов
В Gherkin можно ставить теги, чтобы запускать разные группы сценариев в разное время:
@smoke
Сценарий: Свободное время можно забронировать
...
@ui @slow
Сценарий: Сотрудник бронирует комнату через форму
...Быстрые сценарии запускаются при каждом коммите, помеченные @ui и @slow в отдельном этапе или по ночам.
Перевёрнутая пирамида
Типичная ошибка: большинство проверок написано через UI, а юнит-тестов почти нет. Эту картину называют «рожком мороженого». Прогон долгий, тесты хрупкие, а причину падения приходится искать в браузере. BDD здесь ни при чём: проблема в выборе уровня.
Как выбрать уровень
Задайте три вопроса:
1. Можно ли проверить это правило без интерфейса? Если да, проверяйте без него.
2. Нужно ли, чтобы это читал бизнес? Если да, пишите сценарий на Gherkin. Если нет, хватит юнит-теста.
3. Что сломается, если правило нарушится? Чем выше цена ошибки, тем важнее продублировать проверку на втором уровне.
Итог
BDD и тестовая пирамида дополняют друг друга: BDD отвечает на вопрос, что проверять и на каком языке описывать, а пирамида подсказывает, где это запускать. В седьмой части, «Типичные ошибки и антипаттерны», разберём, что идёт не так, когда этим принципам не следуют.
На каком уровне у вас сейчас больше всего тестов? Похожа ли ваша картина на пирамиду?