Pull to refresh

Comments 36

Честно говоря, статья так и не раскрыла разницу между понятиями «тест» и «должен», функциональное тестирование и unit-тестирование понятия иногда расходящиеся, иногда сходящиеся.

Почему бы «должен» не отнести к «метод А должен возвращать 1, если передали 0», реализация проверки есть самый настоящий «тест».

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

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

Более, того, на мой взгляд необосновано замолчено грандиозное требование TDD к использованию: код, который вы разрабатываете, должен предполагать автоматическое тестирование (!) Данный принцип позволяет проектировать архитектуру приложения исходя из возможности его тестирования автоматическими unit-тестами.

Аббревиатура BDD мне не очень известна, но известен инструмент FIT (и его аналоги), есть некоторые обзоры тут: lobasev.ru/search/label/FIT

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

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

Нет, в BDD тесты пишет сам программист, так же как и в TDD. А то что синтаксис библиотеки RSpec выглядит как BNL — это синтаксический сахар Ruby.
И все-таки BDD и TDD соперники, нет смысла писать юнит тесты если есть спецификации. BDD можно рассматривать как новый слой абстракции над юнит тестами. Если там мы просто проверяем равенства и т.п., то тут проверяем соответствия поведения реальной функции/объекта с поведением описанным в спецификации, правда используя теже методики:)(всмысле проверка на равенство и т.д.)
Вот я не понимаю, почему Вы различаете тесты и спецификации? Спецификация — это такой же тест, только описываемый декларативно (на языке бизнеса чаще всего).

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

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

Единественное отличие, которое я вижу, то в BDD просто используется более высокоуровневое тестирование, обычно именуемое как автоматическое функциональное тестирование.

А что касается написания BDD тестов разработчиками, то на мой взгляд это отнюдь не преимущество по сравнению с идеями FIT. В данном ключе BDD — это тот же TDD, просто чуть более высокоуровневый.

Настоящее преимущество методика получает при использовании ее пользователем (заказчиком), который точно знает как ему нужно, а не как написано в спецификации.

«Более того, TDD не обязательно следует применять для проверки равенства. Применяйте методику для тестирования логики по спецификациям.»

Вот так и появилось BDD:) И это уже более высокий уровень чем assertEquals и т.п.

«В данном ключе BDD — это тот же TDD, просто чуть более высокоуровневый.»
По сути, так и есть, я и написал выше что его можно рассматривать как слой абстрации над TDD.

А то что касаеться FIT, вы просто путаете функциональные тесты с BDD. Функциональное тестирование, которое может проводить не только программист но и тестер и пользователь, прежде всего подразумавает «черный ящик», т.е. тестирующий не имеет представления как это работает, и тестирует некие функиональные куски и их интеграцию. В BDD пользователь конечно может прогнать тесты, но вот написать — врядли.
«Вот так и появилось BDD:) И это уже более высокий уровень чем assertEquals и т.п.»

Я кажется понял откуда ноги растут: вы действительно сравниваете unit-тестирование с TDD?

В моем понимании TDD — это совсем не фреймворк для unit-тестов, это методика разработки, использовать там assertEquals или test.CheckLogicIsCorrectlyImplemented() не регламентируется TDD, это всего лишь подход к разработке: сначала тест, потом логика.

«А то что касаеться FIT, вы просто путаете функциональные тесты с BDD»

Мне почему-то все же верится, что я ничего не путаю, поскольку BDD и есть фукнциональное тестирование, опять же основываясь на Вашей статье: «Мышление в терминах функциональности (того, что код должен делать)...»

В моем понимании необходимо два типа тестирования функционала (не считая нагрузки, совместимости, масштабируемости горизонтальной и вертикальной и т.п.):

1. unit-тестирование, когда разработчик проверяет и фиксирует спецификацию к некоторому алгоритму, участку кода

2. функциональное тестирование, когда QA или заказчик смотрит на систему не со стороны кода и конкретных алгоритмов, а с наружи, со стороны пользователя и пытается получить от системы ответы согласно функциональности системы.

Хочу заметить, что TDD как таковое может покрывать как первый, так и второй тип тестирования, то есть написание тестов может начаться:

а) до разработки логики (пишется программистом)
б) до поставки продукта QA или заказчику на приемку (пишется QA или закачзиком)

В этом смысле Ваше BDD есть некоторое расширение классического unit-тестирования и не более того.

Статья не моя:) Лично я считаю что функциональное тестирование и BDD — это разные вещи.
Еще нужно добавить, для точности, что вообще то юнит тестирование не тоже самое что и TDD.
Юнит тестирование — это метод тестирования, а TDD — это подход к разработке кода, основанный на юнит тестировании.
Точно также и с BDD. В общем случае можно сказать что тестирование поведения это и есть функциональное тестирование, когда тестируется черный ящик. Но BDD — это подход к написанию кода, используя тесты поведения по спецификации. Что нам и демонстрирует фреймворк RSpec.
В целом со всем согласен, за исключением: «TDD — это подход к разработке кода, основанный на юнит тестировании»

TDD — это подход к разработке кода, основанный на *модульном* тестировании, то есть на создании тестов невидимых и недоступных QA или закачзику.

Из описания BDD в википедии прямым текстом следует (encourages collaboration between developers, QA and non-technical or business participants), что эта методика нацелена на разработку единых тестов для всех ролей, именно функциональных, описанных на языке бизнеса.

И противопоставление к TDD основывается как раз на том, что в TDD готовятся тесты понятные только разработчикам, а в BDD тесты понятные всем.

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

Посмотрите на FITPro, например, это в чистом виде BDD методика: тесты пишутся на бизнес-языке, они являются требованиями для разработки, несколько тестов можно объединить и получится спецификация на бизнес-правило.

Понял причину нашего спора:) Вы смотрите на TDD/BDD более широко, с точки зрения общего цикла разработки ПО. Эта же статья и сам фреймворк RSpec нацелены на BDD только в контексте написания кода.
Для менеджера BDD одно, для программиста другое:)
Да, да, классический случай:

— мы используем Agile!
— а кто у вас Product Owner?
— ну как же, менеджер проекта…

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

Причем функциональные тесты пишут разработчики, хотя всем известно, что такие вещи должны делать QA или заказчик (в случае Agile).
Можете указать, где именно спорный момент у автора?

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

Т.е., по сути, отличие BDD от TDD только в том, в каком виде разработчику удобно писать тесты для кода (но не функциональные/UX-тесты).
«Можете указать, где именно спорный момент у автора?»

Да, конечно, "… Behavior Driven Development и чем данная техника отличается от Test-Driven Development"

Согласен с тем, что BDD полностью укладывается в методику TDD, и поэтому ничем не может отличаться. Комментом выше уже предположил, что автор путает unit-тесты (assertTrue, assertFalse) и TDD.

Если отталкиваться от сравнения Unit-тестов и BDD, то конечно BDD иногда может быть удобнее, но поскольку BDD закрывает пробел между unit-тестами и функциональными тестами, то в этом и проявляется сложность вопроса: относится ли BDD к функциональным тестам или нет, поскольку можно написать такой тест, что он будет полностью повторять функциональный, поскольку оперируем бизнес-понятиями (то чем оперирует QA и закачзик), а не объектами и элементами архитектуры (то чем оперирует разработчик)

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

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

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

По TDD мы должны иметь

а) спецификацию на модуль
б) потом делать модуль и разрабатывать модульные тесты вперед
в) потом проводить функциональное тестирование QA
г) потом проводить приемочное тестирование заказчиком

все эти активности базируются на исходных требованиях

По BDD мы должны иметь:

а) спецификации в смысле BDD, не требования, а именно бизнес-описание поведения системы

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

Разница очевидна.

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

Пока остаюсь при своем мнении:

TDD и BDD можно и даже наверно нужно использовать совместно, поскольку TDD ориентирована на техническую составляющую: проверить DAO, проверить согласованность всяких XML-файлов, проверить работоспособность сугубо технических аспектов (логирование, как пример). BDD ориентировано на бизне-логику. Как известно, помимо бизнеса в реальном приложении масса сугубо технических задач, которые бизнесу вообще до фонаря.
Так, я подумаю, как донести свою точку зрения :)

Но сразу могу сказать про последний абзац.
«Как известно, помимо бизнеса в реальном приложении масса сугубо технических задач, которые бизнесу вообще до фонаря.»

Можете представить всю системную часть как «бизнес-логику» работы вашей же архитектуры, системы.

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

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

Ибо тесты также точно описывают бизнес-поведение системы. С точки зрения процесса разработки, думаю, это просто 2 разных способа делать одно и то же.

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

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

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

Я покопаю тему концепции BDD еще.

Отдельно об этом:

Отдельно об этом:

«Согласен, что любую системную фичу можно вытащить на уровень бизнеса, не знаю будут ли они только вам благодарны, скорее скажут: это ваше дело какие там библиотеки используются.»

Речь вовсе не идет о том, что что-то куда-то вытаскивать. Не нужно системные фичи на уровень бизнеса вытаскивать. Я говорю о том, что системные фичи точно так же, как и бизнес-логику, можно тестировать с помощью этих спецификаций.
Об этом и речь: если есть спецификация для тестирования системной фичи, то по определению, она должна быть написана на языке бизнеса, и скорее всего писать ее заказчику или аналитику.
Здесь встает вопрос ролей. Назовем этих людей не заказчиком и аналитиком, а более общим термином — «owner». В случае системных фич, owner'ом может быть архитектор, технический руководитель и разработчики.
И сразу же встает другой: зачем архитектору описывать спецификацию на понятном бизнесу языке? Ему куда как проще в терминах тестов все описать.
Странный вы пример привели. «TestNG, Selenium и FEST»… Selenium — это вообще функциональное тестирование, что не есть основа TDD. Я бы привел в пример множество фреймфорков семейства xUnit для самых разных языков и технологий.
TDD — это одна из крайностей разработки. В это схеме работы очень сложно создать нормальную архитектуру приложения. Ибо если использовать другую крайность — «нормальную разработку», то сначала надо создать спецификацию (srs), потом разработать архитектуру, потом высокоуровневое проектирование и тд…

Я бы лично комбинировал данные подходы к разработке ПО
UFO just landed and posted this here
BDD1
BDD2
А у вас реально можно было ограничится ссылками ;)
И да, я, собственно, перенес бы подобную статью в блог TDD. Тестирование — это немного другое и несколько сбивает с толку.
Я бы вообще в Ruby перенес, про RSpec ведь. Жалко в два блога поместить нельзя.
Темы TDD, BDD и все, что за ними тянется(unit test, CI, refactoring и так далее) настолько обширны, что пытаться их изложить в какой-то одной статье неблагодарное дело. Когда пытаешься все это прицепить к какой-либо технологии, то получается вообще каша, а сама статья вызовет еще кучу вопросов и нареканий(сам с этим столкнулся).
Поэтому я бы писал статью только про саму технологию и как именно она позволяет использовать те или иные приемы TDD(Предполагая, что аудитория знакома с техникой tdd). При это стараясь не вдаваться в теорию.
Или же написать цикл статьей посвященных исключительно TDD и BDD, максимум давай небольшие примеры.
по мне так там сильно все притянуто за уши. Отличие лишь в том, что framework позволяет название метода разложить в текст (расставить пробелы).

а спецификация все равно пишется на PHP, тестировщикам и заказчикам это явно не понравится. А как разработчику мне все равно как будет текст написан camel-ом или через пробел.
ну в php есть вообще проблема с нормальным TDD фреймворком, для phpunit нет человекопонятного гуя + вагон пир зависимостей, simpletest очень медленно развивается в trunk, тк нет интереса разработчиков, а интересующихся сразу же переманивают к phpunit показывая икону zend framework

phpspec я привел лишь как пример уже работающего фреймворка для тех кто хочет пробнуть свои силы.
Sign up to leave a comment.

Articles