Что такое BDD? Опыт с Cucumber/Gherkin + вопросы на собеседовании

Практика BDD в автоматизации QA — гайд по Cucumber/Gherkin — вопросы на собеседовании по BDD/Cucumber

Сейчас узнаем, что такое BDD и как оно работает; плюсы-минусы и подводные камни; как в одной международной компании выбрали BDD и не пожалели; постараемся запомнить лучшие практики BDD; ну и посмотрим на примеры BDD на Gherkin (много).

Содержание

Что такое BDD-разработка, как она применяется в QA

“Разработка через поведение” (BDD — Behavior Driven Development) в QA — это легко читаемые человеком, не владеющим языками программирования, описания требований к продукту — как основа процесса тестирования. Такие тесты являются реюзабельными — то есть могут применяться многократно без больших изменений, но если все-таки понадобится изменить какие-то детали, это будет легко. BDD-тесты предназначаются, в основном, для проверки функциональных компонентов, и далее применяются повторно на более высоком уровне тестирования, что ускоряет пайплайн.

Самое частое применение BDD-метода — это UAT-тесты (User Acceptance Tests, то есть пользовательское или приемочное тестирование). Такие тесты строятся на user story (что это?) и на бизнес-требованиях, и имеют особенность: они пишутся в форме, хорошо воспринимаемой человеком, как бы на обычном языке. Разумеется, “обычный язык” здесь следует понимать ограниченно, поскольку в нем все-таки заданы рамки, есть строго определенные вещи. Основа, или “скелет” тестов может быть написан product owner-ом (или владельцем продукта — здесь можно почитать, кто это?), или бизнес-аналитиком.

BDD-тесты пишутся так, чтобы их мог прочесть человек, не знающий языков программирования (но знающий английский, хотя бы минимально)

Первый шаг, предпринимаемый командой при внедрении BDD — создать некие общие определения, понимаемые стейкхолдерами (кто это?), экспертами в какой-то области (domain experts), разработчиками, и конечно тестировщиками. Этими определениями будут описываться основные модули продукта, события, и ожидаемые (пользователями) результаты. То есть сначала создается набор терминов, согласованный всеми участниками. Это важно, потому что это фактически определяет успешность внедрения BDD.

Основной позитив от BDD состоит в том, что практически все члены команды, как технические специалисты, так и “другие” — способны быстро понять и оценить результаты тестов, и в целом им легче работать с такими тестами.

Какие фреймворки применяются в BDD?

  • Во первых, Cucumber
  • Quantum (это для Java на Андроиде и/или iOS)
  • SpecFlow (это для .NET)
  • Jbehave (это для команды, овладевшей Groovy/Kotlin/Scala)
  • Codeception (для PHP)

Как мы выбрали BDD и не пожалели

На начальном этапе, когда проект только стартовал, когда кто-то предлагает переключиться на новую методологию BDD, опытные лиды учитывают, что начальная подготовка BDD-проекта почти наверняка будет дольше и сложнее, чем все привыкли на старых методологиях. Просто потому что раньше все шло “по накатанной” — есть более-менее стандартный проект; с какой-то автоматизацией; его предполагаемая структура более-менее известна; все знают что делать; берется фреймворк автоматизации, известный вдоль и поперек, настраивается веб-драйвер, или API-шлюз, выбирают язык программирования из короткого списка, ну и пишут первые тесты.

С BDD-проектом так вряд ли получится так просто, сначала понадобится больше времени и усилий. Этапы выбора языка и прочее остаются, и добавляется “экстра” — о чем речь шла выше, “общий словарь терминов”, который будет понятен буквально каждому члену команды, что иногда непросто; по опыту, этот шаг занимает много времени.

BDD лучше подходит для долгосрочных проектов, особенно корпоративных, для крупных заказчиков. В таких проектах плюсы BDD проявятся. Если же проект запланирован на год или меньше, то “лучше идти по пути без BDD” — так, видимо, будет проще, быстрее, и дешевле.

Если проект “большой”, корпоративный, то есть подходит для BDD — то скорее всего для фронтэнда вполне сгодятся имеющиеся тестовые инструменты; условно для прокликивания веб-элементов можно применять стандартную связку типа Browserstack+Selenium. Для бэкэнда можно Postman+Smartbear.

BDD подходит для крупных долгосрочных только-начатых проектов потому, что там обычно большое количество реюзабельных тестовых компонентов, шагов и функций, которые должны быть понятны всем членам QA-команды, разбросанной по миру. Но BDD вряд ли идеально подойдет для сложных проектов с большим количеством уже написанных модулей, ибо рефакторить имеющийся код “под BDD” может быть довольно-таки затратно по времени.

Плюсы BDD

  • Поддерживается английский, понятный каждому тестировщику — т.н. Simple English с ограниченным словарем, и + еще 70 языков (включая русский, разумеется)
  • Тесты по идее понятны любому члену команды
  • Позволяет поддерживать в команде высокий уровень вовлеченности и понимания продукта
  • Экономятся деньги и усилия, при правильном внедрении
  • QA-персонал прокачивает свой уровень компетенций, интуитивно обучаясь

Минусы BDD

  • Медленнее деплой
  • Могут быть проблемы на этапе деплоя
  • Много как бы “лишних” классов, функций, этапов, с точки зрения некоторых педантов
  • Нужна очень хорошая коммуникация в команде, и очень опытные лиды
  • Проект в целом получается “сложнее”, если нужен рефакторинг существующего кода
  • Документация…

Что такое Gherkin

Это так называемый business-readable язык программирования, описывающий бизнес-поведение, на котором пишется “скелет тестов”, без глубокого погружения в детали имплементации функций. Геркин — это как бы “простая речь”, описывающая use-кейсы (что это?), и позволяющая логически описать тесты действий пользователя. Gherkin основан на Словаре Treetop, существующем на 70 языках. Поэтому вся команда может писать тесты на любом из этих 70 языков.

Но — в большинстве случаев все-таки пишет на Basic English.

Ключевые слова Gherkin

  • Feature
  • Background
  • Scenario
  • Scenario Outline Examples
  • Given
  • When
  • Then
  • And
  • But

Пример синтаксиса Gherkin:

Feature: Title of the Scenario
Given [Preconditions or Initial Context]
When [Action/Event or Trigger]
And [Join]
But [Join]
Then [Expected output/ Result]

Как мы переходили на Gherkin

Наша dev-команда не имела никакого опыта с BDD. Во всех наших проектах мы не задумывались о BDD, просто потому что считали “это что-то несерьезное”. Убедила нас параллельная QA-команда из другой страны, продемонстрировав на практике, как это делается, и чем эффективно.

Коллеги продемонстрировали, как их один тестировщик может писать в среднем за день 10 тестов бэкэнда. Это показалось интересным. Также показалось практичным то, что наш новый большой проект требовал проведения всех возможных автотестов (бекэнд, фронтэнд, производительности, безопасности), а команда интернациональная. На этом этапе мы уже склонились к BDD и Cucumber — как популярному фреймворку в этой сфере, с бесплатными обновлениями и (уже) большим комьюнити. Выбран был также фреймворк Serenity для управления тестами и репортов, и Kotlin как “основной” ЯП. Планировалось автоматизировать тесты функциональные/интеграционные/приемочные/сквозные, то есть как бэкэнд, так и фронтэнд.

Проект был достаточно сложным, в QA работали еще параллельно команды из Южной Азии (Индонезия) и Восточной Европы (Словакия). Это было решение для интернет-банкинга, клиенты — банки, корпорации и частные лица.

В первые месяцы QA-команда наполнялась с трудом, т.к. на рынке ощущался дефицит тестировщиков-автоматизаторов с опытом, особенно в Cucumber/Gherkin. Из-за недостатка тестировщиков мы были вынуждены набирать людей вообще без опыта в автоматизации. И тут-то сказалось удобство BDD и простота синтаксиса Gherkin, особенно что касается индонезийских тестировщиков, плохо владеющих ЯП, но имевших опыт в написании feature-файлов (изначальный “скелет” тестов), и владевших Basic English. Они сильно помогли в начале, и благодаря им остальные члены QA-отдела смогли написать и автоматизировать нужные тесты.

Далее со “скелетом” поработали бизнес-аналитики, расширили его, особенно в части приемочных тестов. Вся переписка в QA-команде была на Basic English, как и сами тесты. Тестировщики-индонезийцы разговаривали “на своем” с ручными тестировщиками, тоже индонезийцами, которые локально работали с manual-тестами. Опытные лиды знают, какой проблемой бывает коммуникация между людьми в remote-командах из далеких, иногда весьма экзотических, стран; уровня native-english ожидать не приходится, обычно это Basic English с резким акцентом. Самые блестящие тестировщики-индонезийцы сначала страдали от непонимания, что им делать, особенно это касалось бизнес-требований; manual-тестировщики сначала вообще не могли понять, чего от них хотят; BDD/Gherkin помог в таких ситуациях, стал как бы посредником, благодаря Basic English, который знают, в общем-то, все люди в ИТ — простым языком описывалось, что должно быть протестировано, и почему, и что получится в результате.

Итак, BDD/Gherkin годен, если:

  • Новый крупный проект
  • Требуется оперативность внесения правок (новых требований)
  • QA-команды удаленные и плохо понимающие друг друга
  • Бизнес-аналитики тоже бывают “местными” и их бывает мало
  • В команде много людей без технического бэкграунда и много местных manual-тестеров

Практика — проект в Cucumber

Как выглядит проект в Cucumber, как выглядят автотесты в Cucumber, и чем они отличаются от обычных, не-BDD-тестов

В “стандартном”, не-BDD-проекте у нас стандартно был один Test Class (тело теста) и один Step Class (логика). В BDD-проекте обычно надо “делить” эти классы на дополнительные вложенные. 

В нашем BDD-проекте Test Class был разделен на feature-файл и сам тест, а Step Class разделили на Step Definition и Steps.

Ниже показаны примеры, как это выглядит.

Feature-файл на Gherkin:

Scenario Outline: Creating requests with absence of mandatory fields
When I create POST request for ACCOUNT without mandatory <param>
Then expected status code for request is 400
Then I should get status code ERRORExamples:
| param |
| ID |
| NAME |
| CODE |

Создание запросов при незаполненных обязательных полях

Здесь “ACCOUNT”, “400”, “ERROR” — это параметры этапов; <param> — для повторения этапов. 

Файл Step Definition: Функции с аннотациями (объяснение текста в feature-файле — логика, как мы помним, вынесена в отдельный файл)

Текст связан с кодом через аннотацию (с применением Regex-аннотации):

@When(“^I create POST request for (.*) without mandatory (\\<?\\w+\\>?)$”)
fun i_create_post_without_param(endpoint : Endpoints, param : String) {
baseSteps.createPOSTRequest(URL.API_GATEWAY, path = endpoint,
bodyContent = JsonGenerator().generateJSON(accountGroup),
authorization = baseSteps.token)
}@Then(“^expected status code for request is (\d+)$”)
fun status_code_for_request(statusCode : Int) = baseSteps.checkStatusCode(statusCode)@And(“^I should get status code (.*)$”)
fun get_status_code(statusCode : ResponseMessages) = baseSteps.validateStatusCode(statusCode)

Файл Steps: — Тестирование логики в StepDefinition-файле

Файл Test: “склеивание” feature-файла и StepDefinition-файла (это делает glue-параметр)

@RunWith(CucumberWithSerenity::class)
@CucumberOptions(
features = [“src/test/resources/features/film/create.feature”]
plugin = [“pretty”],
glue = [“com.name.stepdefinitions.film”,
“com.name.stepdefinitions.common”])class Create

В glue-параметре может быть больше одного Steps / Definitions, но в Feature-файле должна быть только одна функция.

Features в Cucumber + примеры

Итак, базовые понятия есть, приступим к практике. 

Background (Предыистория)

Часто бывает, что этапы повторяются во всех сценариях, связанных с Feature-файлом.

Если этапы повторяются в каждом сценарии, это значит, что эти этапы не очень важны для описания сценариев; это получаются неважные этапы. Их можно как бы “отодвинуть назад”, сгруппировав в секции Background.

Это позволяет внести некий контекст в сценарий. В секции может быть несколько этапов, которые выполняются перед каждым сценарием. Background вставляется перед первым Scenario/Example, с тем же отступом:

Background:
Given I get token for admin from NETFLIX_EU appScenario: Searching fantasy film
When ……
Then ……
And ……Scenario: Searching anime from JAPAN for each region
When ……Scenario: Searching anime from JAPAN for ASIA region
When ……

Regex’ы в аннотациях

В Cucumber есть альтернатива “классическим” Regex’ам (более интуитивные регексы, как считают создатели Cucumber). Но в целом, бывает достаточно “классических”.

@And(“^I have (\d+) cucumbers in my belly$”)
fun countCucumbers(value : Int) = baseSteps.getCucumber(value)

Здесь: 

Выражение [ \d+ ] допускает только целый (integer) параметр в feature-файле; когда пользователь вводит например 2,5 — выдается сообщение об ошибке в feature-файле.

Выражение [ @And(“^  ] — в каждом из элементов ( .* )-массива. “Точка со звездочкой” ( .*) служит как замена “любого символа” (так называемый “джокер”)

(Вообще, в feature-файле допустимы любые символы/цифры/знаки).

Выражение в скобках [ (was|wasn’t) ] после слова response можно писать только в такой форме (was или wasn’t) — другое написание будет некорректным. 

@And(“^I should get status code (\\<?\\w+\\>?)$”)

Regex-выражение [ \\<?w+\\>? ] — когда два разных типа строк, первая это стандартная строка ( “test” ), вторая — если она параметр, типа “<test>” то есть с вложенными символами. < and > — необязательный параметр.

Подробнее см. раздел документации по Regex.

Таблицы данных (Data Tables)

Таблицы данных в Cucumber применяются в Scenario Outline, когда тестовый сценарий повторяется несколько раз. Тогда не нужно инициализировать таблицы данных, Cucumber делает это автоматически:

Scenario Outline: Testing endpoint accessibility for update filmGiven I get token for <user> from <app> app
When I create PUT request for FILM with all parameters
Then expected status code for request is 400
And I should get status code ERRORExamples:
| user | app |
| maker | NETFLIX_EU |
| admin | NETFLIX_AS |
| regular | NETFLIX_NA |

Иногда нужно отправить еще какие-то параметры в тест-кейс, в котором шаги не будут повторяться.

And in response was displayed parameters:
| name | start_date | type | episodes |@And(“^in response (was|wasn’t) displayed parameters?$”)
fun response_display_parameters(visibility : String,
data : DataTable) = baseSteps.getParams(data)@Step
fun getParams(parameterTable : DataTable) : Map<String,Any> {
val tableMaps : MutableList<MutableMap<String,String>> = parameterTable.asMaps() val loadedValues = tableMaps[0]
val transforms = tableMaps[1]
return loadedValues.entries.map { (param,valueKey) ->
val loadedValue = if (valueKey.isNullOrEmpty()) "" else DataLoader.getValue(valueKey) val transform = transforms[param]
val finalValue = processValueTransform(transform.toString(),loadedValue)
Pair<String,Any>(param,finalValue)
}.toMap()
}

Как видим здесь, надо «прописать» этот параметр и указать тип DataType в StepDefinition-файле; это дольше и сложнее, но потом экономит время.

Больше примеров — здесь.

Как выглядят тесты на Gherkin в полностью русскоязычных проектах, можно посмотреть здесь.

***

Контрольные вопросы / Собеседование QA по Cucumber

Что такое Cucumber?

Cucumber — это огурец! А для тестировщика Cucumber — это основной рабочий фреймворк, если он работает по BDD.

А что такое BDD? Зачем нужно BDD?

BDD — это “разработка через тестирование”, специфическая Agile-методология для «разрушения технического и языкового барьера» между бизнес-аналитиками, владельцами продукта, разработчиками и тестировщиками.

Как связаны BDD и TDD?

TDD — это Test Driven Development, разработка через тестирование”. BDD-методология возникла как “продолжение” TDD. BDD основана на принципах TDD. Здесь чуть подробнее о TDD.

А чем отличается BDD и TDD?

Поскольку BDD это развитие идеи TDD, то BDD как бы направлен на устранение проблем, которые не может решить TDD. Подробный материал о BDD и TDD по ссылке.

Что такое Геркин?

Геркин (Gherkin) — это маленький соленый огурец из банки, употребляемый в качестве закуски. А для тестировщика Gherkin — это специфический язык программирования, который выглядит “почти как человеческий язык”, понятный не-технарям, при этом сохраняющий “формальность” классических языков программирования — это нужно для автоматической обработки такого текста, то есть применения в автоматизированных тестах. 

Другое определение Gherkin: легко читаемый язык описания желаемого поведения системы.

Как определить, что это сценарий на Gherkin?

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

chto-takoe-bdd-i-kak-perejti-na-cucumber-gherkin

Что должно быть в Feature-файле?

“Высокоуровневое” описание приложения. Первая строчка feature-файла должна начинаться с ключевого слова “Feature”, далее идет описание функции. В этом файле обычно несколько сценариев. Файл должен иметь расширение *.feature.

Какие ключевые слова Gherkin знаете?

Наиболее часто применяемые: 

  • Given
  • When
  • Then
  • And

Зачем нужен файл Scenario Outline в Cucumber?

Это файл с параметризацией сценариев. Когда один сценарий “принимает” много наборов тестовых данных, а этапы остаются те же. 

А какие (еще) языки программирования поддерживает Cucumber?

Практически все применяемые в QA, типа Java, Python (есть библиотека Behave), есть Cucumber.js. 

Обычно Feature-файлы пишутся на Gherkin, а StepDefinition-файлы — на стандартных ЯП.

(Разумеется, Cucumber может интегрироваться с Selenium.)

Зачем нужен файл Step Definition в Cucumber?

Выполняет тест по шагам-этапам и проверяет результаты. Каждый шаг (выполнения) в Feature-файле соответствует какому-то методу в StepDefinition-файле.

Сколько сценариев может быть в Feature-файле?

Максимум 10, обычно их меньше.

Сколько шагов (этапов) может быть в одном сценарии?

Не более 3, или 4.

Может ли Cucumber работать с Selenium Webdriver?

Да, может, здесь туториал (англ).

Какой была ваша первая зарплата в QA и как вы искали первую работу?

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии

Мы в Telegram

Наш официальный канал
Полезные материалы и тесты
Готовимся к собеседованию
Project- и Product-менеджмент

? Популярное

? Telegram-обсуждения

Наши подписчики обсуждают, как искали первую работу в QA. Некоторые ищут ее прямо сейчас.
Наши подписчики рассказывают о том, как не бояться задавать тупые вопросы и чувствовать себя уверенно в новой команде.
Обсуждаем, куда лучше податься - в менеджмент или по технической ветке?
Говорим о конфликтных ситуациях в команде и о том, как их избежать
$1100*
медианная зарплата в QA в июне 2023

*по результатам опроса QA-инженеров в нашем телеграм-канале

Собеседование

19%*
IT-специалистов переехало или приняло решение о переезде из России по состоянию на конец марта 2022

*по результатам опроса в нашем телеграм-канале

live

Обсуждают сейчас