Поведенческая разработка - Behavior-driven development

В программной инженерии разработка , управляемая поведением ( BDD ) - это гибкий процесс разработки программного обеспечения, который поощряет сотрудничество между разработчиками, тестировщиками обеспечения качества и представителями клиентов в рамках проекта программного обеспечения. Это побуждает команды использовать беседу и конкретные примеры для формализации общего понимания того, как должно вести себя приложение. Он возник в результате разработки через тестирование (TDD). Поведенческая разработка сочетает в себе общие методы и принципы TDD с идеями предметно-ориентированного проектирования и объектно-ориентированного анализа и проектирования, чтобы предоставить командам разработчиков и менеджеров программного обеспечения общие инструменты и общий процесс для совместной работы над разработкой программного обеспечения.

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

BDD в значительной степени упрощается за счет использования простого предметно-ориентированного языка (DSL), использующего конструкции естественного языка (например, предложения на английском языке), которые могут выражать поведение и ожидаемые результаты. Сценарии тестирования уже давно являются популярным приложением DSL с разной степенью сложности. BDD считается эффективной технической практикой, особенно когда «проблемное пространство» бизнес-задачи, которую необходимо решить, является сложным.

История

Разработка на основе поведения - это расширение разработки на основе тестирования, процесса разработки, в котором используется простой DSL. Эти DSL преобразуют структурированные операторы естественного языка в исполняемые тесты. Результатом является более тесная связь с критериями приемки для данной функции и тестами, используемыми для проверки этой функциональности. Таким образом, это естественное продолжение тестирования TDD в целом.

BDD фокусируется на:

  • С чего начать в процессе
  • Что тестировать, а что не тестировать
  • Сколько тестировать за один раз
  • Как называть тесты
  • Как понять, почему тест не проходит

По сути, BDD - это переосмысление подхода к модульному и приемочному тестированию , чтобы избежать проблем, которые возникают естественным образом. Например, BDD предлагает, чтобы имена модульных тестов представляли собой целые предложения, начинающиеся с условного глагола (например, «should» на английском языке), и их следует писать в порядке деловой ценности. Приемочные тесты должны быть написаны с использованием стандартной гибкой структуры пользовательской истории : «Как [роль / действующее лицо / заинтересованное лицо ] я хочу, чтобы [функция / возможность] приносила [выгоду]». Критерии приемлемости должны быть написаны в терминах сценариев и реализованы в классах: учитывая [исходный контекст], когда [событие происходит], затем [обеспечить некоторые результаты] .

Начиная с этого момента, многие люди разрабатывали BDD-фреймворки в течение многих лет, наконец, образуя их в терминах среды общения и сотрудничества для разработчиков, QA и нетехнических или бизнес-участников программного проекта. Во время «Agile-спецификаций, BDD и Testing eXchange» в ноябре 2009 года в Лондоне Дэн Норт дал следующее описание BDD:

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

Во время интервью с Дэном Нортом на конференции GOTO в 2013 году Лиз Кеог определила BDD как:

Он использует примеры, чтобы обсудить, как ведет себя приложение ... И обсудить эти примеры.

Дэн Норт создал структуру BDD, JBehave , а затем фреймворк BDD на уровне истории для Ruby под названием RBehave, который позже был интегрирован в проект RSpec . Он также работал с Дэвидом Челимски, Аслаком Хеллесой и другими над разработкой RSpec, а также над написанием «Книги RSpec: разработка на основе поведения с RSpec, Cucumber и друзьями». Первая основанная на сюжете структура в RSpec была позже заменена Cucumber, в основном разработанной Аслаком Хеллесой . Capybara , которая является частью среды тестирования Cucumber, является одним из таких веб-приложений для автоматизации тестирования.

Принципы BDD

Разработка через тестирование - это методология разработки программного обеспечения, которая, по сути, гласит, что для каждой единицы программного обеспечения разработчик программного обеспечения должен:

  • определить тестовый набор для единицы первого ;
  • сделать тесты неудачными;
  • затем реализовать агрегат;
  • наконец, убедитесь, что реализация модуля обеспечивает успешное выполнение тестов.

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

Разработка, управляемая поведением, указывает, что тесты любой единицы программного обеспечения должны быть определены с точки зрения желаемого поведения единицы. Заимствуя гибкую разработку программного обеспечения, «желаемое поведение» в данном случае состоит из требований, установленных бизнесом, то есть желаемого поведения, имеющего бизнес-ценность для любой организации, заказавшей строящуюся единицу программного обеспечения. В практике BDD это называется деятельностью BDD «вовнутрь».

Поведенческие характеристики

Следуя этому основному выбору, BDD делает второй выбор, касающийся того, как должно быть указано желаемое поведение. В этой области BDD предпочитает использовать полуформальный формат для поведенческой спецификации, который заимствован из пользовательских историй спецификаций из области объектно-ориентированного анализа и проектирования . Сценарий аспект этого формата можно рассматривать как применение логики Хора к поведенческой спецификации программных блоков с использованием языка домена конкретной ситуации.

BDD указывает, что бизнес-аналитики и разработчики должны сотрудничать в этой области и должны определять поведение в терминах пользовательских историй, каждая из которых явно записана в специальном документе. Каждая пользовательская история каким-то образом должна иметь следующую структуру:

Заголовок
Явное название.
Повествование
Короткий вводный раздел со следующей структурой:
  • Как : человек или роль, которые получат выгоду от функции;
  • Хочу : особенность;
  • так что : выгода или ценность функции.
Критерии приемки
Описание каждого конкретного сценария повествования со следующей структурой:
  • Дано : исходный контекст в начале сценария в одном или нескольких предложениях;
  • Когда : событие, запускающее сценарий;
  • Затем : ожидаемый результат в одном или нескольких пунктах.

BDD не предъявляет никаких формальных требований к тому, как именно должны быть записаны эти пользовательские истории, но он настаивает, чтобы каждая команда, использующая BDD, придумала простой стандартизированный формат для записи пользовательских историй, который включает элементы, перечисленные выше. Однако в 2007 году Дэн Норт предложил шаблон для текстового формата, который нашел широкое применение в различных программных инструментах BDD. Очень краткий пример этого формата может выглядеть так:

Title: Returns and exchanges go to inventory.

As a store owner,
I want to add items back to inventory when they are returned or exchanged,
so that I can track inventory.

Scenario 1: Items returned for refund should be added to inventory.
Given that a customer previously bought a black sweater from me
and I have three black sweaters in inventory,
when they return the black sweater for a refund,
then I should have four black sweaters in inventory.

Scenario 2: Exchanged items should be returned to inventory.
Given that a customer previously bought a blue garment from me
and I have two blue garments in inventory
and three black garments in inventory,
when they exchange the blue garment for a black garment,
then I should have three blue garments in inventory
and two black garments in inventory.

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

Этот формат называется языком Gherkin, синтаксис которого аналогичен приведенному выше примеру. Термин Gherkin , однако, относится к программным инструментам Cucumber , JBehave, Lettuce, behavior и Behat .

Спецификация как повсеместный язык

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

Распространенный риск, связанный с разработкой программного обеспечения, включает нарушения связи между разработчиками и заинтересованными сторонами. BDD использует спецификацию желаемого поведения как универсальный язык для членов команды проекта. Это причина того, что BDD настаивает на полуформальном языке для поведенческой спецификации: некоторая формальность является требованием для повсеместного использования языка. Кроме того, наличие такого повсеместного языка создает модель предметной области спецификаций, так что о спецификациях можно рассуждать формально. Эта модель также является основой для различных доступных программных инструментов, поддерживающих BDD.

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

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

Специализированная инструментальная поддержка

Подобно практике проектирования, основанного на тестировании, разработка, основанная на поведении, предполагает использование в проекте специализированных инструментов поддержки. BDD можно рассматривать как более конкретную версию TDD, поскольку она требует предоставления не только тестового кода, но и отдельного документа в дополнение к описанию поведения на более понятном для человека языке. Это требует двухэтапного процесса для выполнения тестов, чтения и анализа описаний, а также чтения тестового кода и поиска соответствующей реализации теста для выполнения. Этот процесс делает BDD немного более трудоемким для работы с разработчиком, но из-за своей удобочитаемой природы ценность этих документов распространяется на еще менее техническую аудиторию и, следовательно, может служить средством коммуникации для описания требований («функций» ).

Принципы инструмента

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

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

  • Инструмент читает документ спецификации.
  • Инструмент непосредственно понимает полностью формальные части повсеместного языка (например, ключевое слово Given в приведенном выше примере). Исходя из этого, инструмент разбивает каждый сценарий на значимые пункты.
  • Каждое отдельное предложение в сценарии преобразуется в своего рода параметр для проверки пользовательской истории. Эта часть требует от разработчиков программного обеспечения работы над конкретным проектом.
  • Затем платформа выполняет тест для каждого сценария с параметрами из этого сценария.

Дэн Норт разработал ряд фреймворков, поддерживающих BDD (включая JBehave и RBehave ), работа которых основана на шаблоне, который он предложил для записи пользовательских историй. Эти инструменты используют текстовое описание для случаев использования, и несколько других инструментов (например, CBehave) последовали их примеру. Однако этот формат не требуется, поэтому есть другие инструменты, которые также используют другие форматы. Например, Fitnesse (который основан на таблицах решений ) также использовался для развертывания BDD.

Примеры инструментов

Существует несколько различных примеров программных инструментов BDD, используемых сегодня в проектах для различных платформ и языков программирования.

Возможно, наиболее известным является JBehave, разработанный Дэном Норт, Элизабет Кио и некоторыми другими. Ниже приводится пример, взятый из этого проекта:

Рассмотрим реализацию Игры Жизни . Эксперт в предметной области (или бизнес-аналитик) может захотеть указать, что должно произойти, когда кто-то настраивает стартовую конфигурацию игровой сетки. Для этого он может захотеть привести пример ряда шагов, предпринятых человеком, переключающим ячейки. Пропустив повествовательную часть, он мог бы сделать это, записав следующий сценарий в текстовый документ (который является типом входного документа, который читает JBehave):

Given a 5 by 5 game
When I toggle the cell at (3, 2)
Then the grid should look like
.....
.....
.....
..X..
.....
When I toggle the cell at (3, 1)
Then the grid should look like
.....
.....
.....
..X..
..X..
When I toggle the cell at (3, 2)
Then the grid should look like
.....
.....
.....
.....
..X..

Жирный шрифт не является частью ввода; он включен сюда, чтобы показать, какие слова распознаются как формальный язык. JBehave распознает термины Дано (как предварительное условие, определяющее начало сценария), Когда (как триггер события) и Затем (как постусловие, которое должно быть проверено как результат действия, следующего за триггером). На основе этого JBehave может читать текстовый файл, содержащий сценарий, и разбирать его на разделы (предложение настройки, а затем три триггера событий с проверяемыми условиями). Затем JBehave берет эти предложения и передает их коду, который может устанавливать тест, реагировать на триггеры событий и проверять результат. Этот код должен быть написан разработчиками в команде проекта (на Java , потому что это платформа, на которой основан JBehave). В этом случае код может выглядеть так:

private Game game;
private StringRenderer renderer;

@Given("a $width by $height game")
public void theGameIsRunning(int width, int height) {
    game = new Game(width, height);
    renderer = new StringRenderer();
    game.setObserver(renderer);
}
    
@When("I toggle the cell at ($column, $row)")
public void iToggleTheCellAt(int column, int row) {
    game.toggleCellAt(column, row);
}

@Then("the grid should look like $grid")
public void theGridShouldLookLike(String grid) {
    assertThat(renderer.asString(), equalTo(grid));
}

В коде есть метод для каждого типа предложения в сценарии. JBehave определит, какой метод соответствует какому предложению, с помощью аннотаций и будет вызывать каждый метод по порядку во время выполнения сценария. Текст в каждом пункте в сценарии , как ожидается , в соответствии с текстом шаблона в коде , для этого пункта (например, Учитывая в сценарии , как ожидается, будет сопровождаться пунктом вида «в X по игре Y») . JBehave поддерживает сопоставление предложений с шаблонами и имеет встроенную поддержку для выбора терминов из шаблона и передачи их методам в тестовом коде в качестве параметров. Тестовый код обеспечивает реализацию для каждого типа предложения в сценарии, который взаимодействует с тестируемым кодом и выполняет тест на основе сценария. В таком случае:

  • В theGameIsRunningметоде реагирует на заданную статью по настройке начальной игры сетки.
  • В iToggleTheCellAtметоде реагирует на When пункт путем обжига от события переключения описано в п.
  • В theGridShouldLookLikeметоде реагирует на Тогда п, сравнивая состояние игровой сетки в ожидаемом состоянии от сценария.

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

Наконец, для запуска тестов JBehave требуется некоторый соединительный код, который идентифицирует текстовые файлы, которые содержат сценарии и которые вводят зависимости (например, экземпляры Game) в тестовый код. Этот соединительный код здесь не проиллюстрирован, поскольку он является техническим требованием JBehave и не имеет прямого отношения к принципу тестирования в стиле BDD.

История против спецификации

Отдельную подкатегорию разработки, основанной на поведении, составляют инструменты, в которых в качестве языка ввода используются спецификации, а не пользовательские истории. Примером этого стиля является инструмент RSpec , который также изначально был разработан Дэном Нортом. Инструменты спецификации не используют пользовательские истории в качестве входного формата для сценариев тестирования, а скорее используют функциональные спецификации для тестируемых модулей. Эти спецификации часто имеют более технический характер, чем пользовательские истории, и обычно менее удобны для общения с бизнес-персоналом, чем пользовательские истории. Пример спецификации стека может выглядеть так:

Specification: Stack

When a new stack is created
Then it is empty

When an element is added to the stack
Then that element is at the top of the stack

When a stack has N elements 
And element E is on top of the stack
Then a pop operation returns E
And the new size of the stack is N-1

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

Инструменты тестирования спецификаций, такие как RSpec и JDave, несколько отличаются по своей природе от таких инструментов, как JBehave. Поскольку они рассматриваются как альтернатива базовым инструментам модульного тестирования, таким как JUnit , эти инструменты, как правило, предпочитают отказ от разделения кода истории и кода тестирования и предпочитают вместо этого встраивать спецификацию непосредственно в код теста. Например, тест RSpec для хеш-таблицы может выглядеть так:

describe Hash do
  let(:hash) { Hash[:hello, 'world'] }

  it { expect(Hash.new).to eq({}) }

  it "hashes the correct information in a key" do
    expect(hash[:hello]).to eq('world')
  end

  it 'includes key' do
    hash.keys.include?(:hello).should be true
  end
end

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

Результатом проверки будет:

 Hash
   should eq {}
   includes key
   hashes the correct information in a key

Три Амигоса

Три Amigos, также называемые «Семинар по спецификациям», представляют собой встречу, на которой Владелец продукта обсуждает требование в форме «Спецификация на примере» с различными заинтересованными сторонами, такими как отдел контроля качества и команда разработчиков. Ключевая цель этого обсуждения - вызвать обсуждение и выявить любые недостающие спецификации. Обсуждение также дает платформу для QA, команды разработчиков и владельца продукта, чтобы сойтись и выслушать точки зрения друг друга, чтобы обогатить требования, а также убедиться, что они создают правильный продукт.

Три Amigos

  • Бизнес - роль бизнес-пользователя заключается только в определении проблемы (а не в попытках предложить какое-либо решение).
  • Разработка - Роль разработчиков заключается в том, чтобы предлагать способы решения проблемы.
  • Тестирование - роль тестировщиков заключается в том, чтобы подвергнуть сомнению решение, выявить как можно больше различных возможностей для мозгового штурма по сценариям «Что, если» и помочь сделать решение более точным, чтобы устранить проблему.

Смотрите также

Рекомендации