Что такое развитие, управляемое поведением ? Формальное определение можно найти в Википедии:
BDD — это гибкая, гибкая методология второго поколения, основанная на принципах извлечения, с участием многих заинтересованных сторон, с множеством масштабов и высокой степенью автоматизации. Он описывает цикл взаимодействия с четко определенными результатами, что приводит к поставке работающего, проверенного программного обеспечения, которое имеет значение.
Краткое, неточное определение разработки, управляемой поведением, может быть следующим: эволюция разработки, управляемой тестами, где спецификации строятся в виде наборов примеров , которые совпадают с автоматизированными тестами. Эти тесты написаны на чем-то похожем на естественный язык , обычно следуя парадигме «дано / когда / потом».
Обратите внимание, что это определение только цитирует то, что BDD добавляет поверх TDD: например, использование mocks — это то, что я считаю само собой разумеющимся.
Как это работает, но самое главное: почему
В BDD спецификации для программного обеспечения записываются в виде файлов функций , которые в основном являются естественным языком, который следует некоторым соглашениям. Каждый функциональный файл содержит несколько сценариев, которые можно рассматривать как изолированные тесты.
Конечно, инструменту, подобному Cucumber или Behat, трудно создавать экземпляры объектов путем интерпретации естественного языка, поэтому за файлом возможностей находится конфигурация, написанная на языке программирования, таком как PHP (Ruby в случае Cucumber).
Конфигурация должна быть написана программистом; однако файлы функций могут быть написаны и поддерживаться экспертом домена или любым не техническим персоналом . Фактически, они могут даже быть написаны до реализации и настройки, как в Acceptance Test-Driven Development.
Лично я не интерпретирую полнометражные файлы как в спецификации: не более слова или PDF документов для обсуждения с аналитиками, но воспринимаемые исполняемые текстовые файлы. Если вы регистрируете документы Word в своей системе контроля версий, как я, подумайте об этом.
Реализация
Файлы объектов — это просто текст. Behat , инструмент, рассмотренный в этой статье, говорит, чтобы сохранить их в виде текстовых файлов с расширением .feature.
Конфигурации я говорил о том , набор шагов определения , что является PHP — код. Каждое определение шага является регулярным выражением, связанным с обратным вызовом. Как только файл объекта будет выполнен, каждая строка будет проанализирована, и ее интересная часть будет сопоставлена с регулярными выражениями. Соответствующее регулярное выражение определяет обратный вызов для выполнения (проще показать пример, чем описать его).
Наконец, среда должна быть предопределена для сценариев: например, эти сценарии будут загружать классы, создавать объекты и импортировать утверждения.
Когда файл компонента готов к выполнению, вы можете запустить свои тесты из командной строки, используя утилиту, которая фактически называется behat и работает почти как PHPUnit. Вы можете установить ее через PEAR за считанные секунды.
Кстати, если вы работаете с Vim, существует простой способ получить подсветку синтаксиса для Gherkin , в которой представлены файлы языковых возможностей.
пример
Я привожу здесь пример финансового расчета с использованием Behat: речь идет о расчете налога на добавленную стоимость с учетом цены и процента от налога, а затем их суммировании для отображения брутто-цены для пользователя. Тестируемый класс — это цена.
Вот пример файла функции:
Feature: VatCalculation
In order to communicate to the client
As an operator
I want to manage value added tax
Scenario: Calculate VAT
Given I have entered 100 into the unit price
And I have entered 20 into the vat percentage
When I make a behavior request
Then The gross price should be 120
Окружающая среда:
<?php
// here you could put require_once() statements, or include some bootstrap file
/**
* I define a simple assertion function here. However, it should be in another file.
* You can also import PHPUnit's assertions: everything that throws exceptions when the assertion fails will work.
*/
function assertEquals($expected, $actual)
{
if ($expected != $actual) {
throw new Exception("$expected is not equal to $actual.");
}
}
/**
* Also the class definition should be in its own file: this file will
* be repeatedly executed.
*/
class Price
{
function setUnitPrice($price)
{
$this->unit_price = $price;
}
function setVatPercentage($vat_percentage)
{
$this->vat_percentage = $vat_percentage;
}
function modifiedVat()
{
$this->gross_price = $this->unit_price * (1 + $this->vat_percentage / 100);
}
function getGrossPrice()
{
return $this->gross_price;
}
}
/**
* The fixture for our tests.
*/
$world->price = new Price();
и определение адекватных шагов:
<?php
$steps->Given('/^I have entered (\d+) into the unit price$/', function($world, $unitPrice) {
$world->price->setUnitPrice($unitPrice);
});
$steps->Given('/^I have entered (\d+) into the vat percentage$/', function($world, $vatPercentage) {
$world->price->setVatPercentage($vatPercentage);
});
$steps->When('/^I make a behavior request$/', function($world) {
$world->price->modifiedVat();
});
$steps->Then('/^The gross price should be (\d+)$/', function($world, $expectedGrossPrice) {
assertEquals($expectedGrossPrice, $world->price->getGrossPrice());
});
Тем не менее, вы не должны копировать этот код, который приведен здесь только для иллюстрации. Вы можете клонировать мой небольшой репозиторий на Github или скачать архив оттуда .
Выводы
Сначала я скептически относился к BDD, так как с технической точки зрения он мало что добавляет к TDD. Но работа над приложениями enteprise открыла мне глаза: я самый технический специалист в моей команде, но я должен сотрудничать и общаться с экспертом (экспертами) в области, чтобы соответствовать требованиям и тому, что пользователь хочет от моего кода ,
BDD открывает новые возможности, такие как работа над спецификациями вместе с деловыми людьми (без программиста, который бы постоянно исправлял синтаксис). Я уверен, что у вас есть по крайней мере один документ с требованиями в вашем офисе, где спецификации больше не синхронизируются с тем, что делает код.
Наконец, тесты на читаемость не могут быть лучше: единственное, что может конкурировать с шагами, определенными на естественном языке, это сообщения с ключевыми словами Smalltalk.