Разделы портала

Онлайн-тренинги

.
Основы BDD: Юнит, Интеграционные и End-to-End тесты
20.04.2018 10:32

Оригинальная публикация: http://automationpanda.com/2017/10/14/bdd-101-unit-integration-and-end-to-end-tests/

Перевод: Анна Радионова

Существует много видов ПО тестов. Практики BDD можно применять в любых аспектах тестирования, но BDD фреймворки используются далеко не во всех типах тестов. Поведенческие сценарии, по сути, являются функциональными тестами - они проверяют, что тестируемый продукт работает корректно. Для тестирования производительности могут использоваться инструменты, в то время как BDD фреймворки не предназначены для этих целей. Задача данной статьи, в основном, состоит в описании роли BDD автоматизации в Пирамиде Тестирования. Прочитайте статью BDD 101: Manual Testing для того, чтобы понимать как BDD применяется при ручном тестировании. (Всю информацию по BDD можно найти на странице  Automation Panda BDD page)

Пирамида Тестирования

Пирамида Тестирования представляет собой подход к разработке тестов, который разделяет тесты на три слоя: юнит, интеграционные и end-to-end.

■    Юнит-тесты - это тесты белого ящика, которые проверяют отдельные части кода, такие как функции, методы и классы. Они должны быть написаны на том же языке, что и тестируемый продукт и храниться в том же репозитории. Они часто прогоняются как часть сборки, чтобы сразу же увидеть успешно ли завершается тест или нет.

■    Интеграционные тесты - это тесты черного ящика, которые проверяют, что интеграционные точки между компонентами продукта работают корректно. Тестируемый продукт должен быть в активной фазе и развернут на тестовом окружении. Тесты сервиса часто являются именно тестами интеграционного уровня.

■    End-to-end тесты - это тесты черного ящика, которые проверяют пути выполнения системы. Их можно рассматривать как многошаговые интеграционные тесты. Тесты для веб-интерфейса часто являются именно end-to-end тестами.

Ниже представлено графическое отображение Пирамиды Тестирования:

Пирамида Тестирования

Сложность тестов отображена по возрастанию: юнит-тесты самые простые и выполняются очень быстро, в то время как end-to-end тесты требуют тщательной настройки, продуманности логики и их прогон длится долгое время. В идеале лучше, чтобы большая часть тестов находилась в нижней части схемы, а в верхней ее части их было меньше. Реализовать тестовое покрытие и изолировать тесты проще на более низкоуровневом этапе, чтобы на более высоком уровне были внедрены более трудозатратные, хрупкие тесты. Перенос тестов в нижнюю часть пирамиды также может свидетельствовать о более широком тестовом покрытии и меньшем времени выполнения. Различные слои тестирования оптимизируют риски и делают его эффективным.

Behavior-Driven юнит-тестирование

Тестовые BDD фреймворки не предназначены для написания юнит-тестов. Юнит-тесты являются низкоуровневыми, программными тестами для проверки отдельных функций или методов. Можно написать Gherkin тест в целях юнит-тестирования, но по факту это перебор. Гораздо лучше использовать уже существующие юнит-тест фреймворки как, например, JUnit, NUnit и pytest.

Тем не менее, BDD практики могут применяться для юнит-тестов. Каждый юнит-тест должен быть направлен на основную составляющую: один вызов, единичная вариация, определенная комбинация ввода; на поведение. В дальнейшем при разработке спецификация поведения фичи четко отделяет юнит тесты от тестов более высокого уровня. Разработчик функционала также ответственен за написание юнит-тестов, в то время как за интеграционные и end-to-end тесты несет ответственность другой инженер. Спецификация поведения является, своего рода, джентльменским соглашением о том, что юнит-тесты будут являться отдельной сущностью.

Интеграционное и End-to-End тестирование

Тестовые BDD фреймворки наиболее ярко проявляют себя на интеграционных и end-to-end уровнях тестирования.

Поведенческие спецификации однозначно и лаконично описывают, на что именно ориентирован тест-кейс. Шаги могут быть написаны на интеграционном или end-to-end уровне. Тесты сервиса могут быть написаны с помощью поведенческих спецификаций, как, например в Karate. End-to-end тесты фактически представляют собой многошаговые интеграционные тесты. Обратите внимание на следующий пример, который, на первый взгляд, кажется базовой моделью взаимодействия с пользователем, но, по сути, является объемным end-to-end тестом:

Given a user is logged into the social media site
When the user writes a new post
Then the user's home feed displays the new post
And the all friends' home feeds display the new post

Простая публикация в социальной сети включает процессы взаимодействия с интерфейсом, вызовы сервисов бекенда и внесение изменений в базу данных в режиме реального времени. Описан полный путь прохождения в системе. Автоматизированные шаги могут покрывать эти уровни явно или неявно, но они совершенно точно покрыты тестом.

Длительные End-to-End тесты

Термины часто понимаются разными людьми по-разному. Когда люди говорят “end-to-end тесты,” они подразумевают продолжительные последовательные тесты: тесты, которые покрывают различное поведение продукта одно за другим.  Это утверждение заставляет содрогнуться приверженцев BDD, т.к это противоречит основному правилу BDD: один сценарий, одно поведение. Конечно, с помощью BDD фреймворков можно составлять длительные end-to-end тесты, но нужно хорошо подумать, стоит ли это делать и как именно.

Существует пять основных принципов написания длительных end-to-end сценариев в BDD:

  1. Не стоит беспокоиться на этот счет. Если BDD процесс поставлен правильно, то каждое отдельное поведение уже полностью покрыто тестовыми сценариями. Каждый сценарий должен покрывать все классы эквивалентности вводимых и выводимых данных. Таким образом, длительные end-to-end сценарии будут являться, в основном, дублированием тестового покрытия. Вместо того, чтобы тратить время на разработку, лучше отказаться от автоматизации длительных end-to-end сценариев, как от тех, которые не представляют большой ценности и уделить больше времени ручному и исследовательскому тестированию.
  2. Объединить существующие сценарии в новые. Каждая When-Then пара представляет собой  индивидуальное поведение. Шаги из существующих сценариев могут быть переопределены в другие сценарии и для этого потребуется лишь незначительный рефакторинг. Это нарушает хорошие практики Gherkin и может привести к появлению длительных сценариев, но это наиболее практичный способ переиспользовать шаги для обширных end-to-end сценариев. Большинство BDD фреймворков не поддерживают пошаговый порядок, а если поддерживают, то шаги должны быть переписаны, чтобы код работал. (Этот подход является наиболее практичным, но менее традиционным.)
  3. Встраивайте проверки в Given и When шаги. Данная стратегия позволяет избежать дуплицирования When-Then пар и убедиться, что проверки производятся. Корректность каждого шага проверяется на протяжении всего процесса с помощью Gherkin текста. Однако, может потребоваться ряд новых шагов.
  4. Воспринимайте последовательность поведений как уникальное отдельное поведение. Это наилучший способ обдумывания длительных end-to-end сценариев, т.к. он усиливает поведенческое мышление. Продолжительный сценарий имеет ценность только в том случае, если он расценивается как уникальное поведение. Сценарий должен быть написан с целью подчеркнуть эту уникальность. В противном случае это не тот сценарий, который стоит использовать. Такие сценарии часто являются декларативными и высокоуровневыми.
  5. Не используйте BDD фреймворки и пишите тесты исключительно с помощью средств автоматизации. Gherkin предназначен для совместной работы в отношении поведения, в то время как продолжительные end-to-end тесты решают проблемы  интенсивности работы QA. Бизнес может предоставить поведенческие спецификации, но никогда не станет писать end-to-end тесты. Переписывание поведенческих спецификаций в длинные end-to-end сценарии может блокировать разработку. Гораздо лучшим решением является сосуществование: приемочные тесты могут быть написаны при помощи Gherkin, а продолжительные end-to-end тесты -  средствами программирования. Для автоматизации обоих наборов тестов можно использовать одну и ту же базу кода, у них могут быть единые модули поддержки и даже методы определения шагов.

Выберите подход, наиболее подходящий вашей команде.

Обсудить в форуме