Что такое TDD и BDD на пальцах, и что должен знать о них фронтендер
Dec 18, 2019 · 3 min read
Постараюсь как можно проще объяснить эти концепции и на примере показать разницу.
❓Что это вообще за буквы
И то, и другое — подходы к разработке, когда сначала пишутся тесты, а потом код.
*DD (*что-то* Driven Development) — разработка, основанная на чем-то.
TDD (Test Driven Development) — Разработка на основе тестов.
BDD (Behavior Driven Development) — Разработка на основе поведения.
BDD, на самом деле, является расширением TDD-подхода. Тем не менее, они предназначены для разных целей и для их реализации используются разные инструменты. В разных командах эти понятия могут интерпретировать по-разному, и часто возникает путаница между ними.
❓В чем разница
❓А как выглядит на примере
Давайте во з ьмем простую задачку. Нам нужно сделать форму, в которую мы вводим возраст котика и его вес, а в ответ получаем, сколько корма котик должен кушать в сутки.
Как подойти к этой задаче, используя TDD подход:
Как подойти к этой задаче, используя BDD подход:
Далее мы это описываем с помощью специального синтаксиса (он зависит от инструмента, который используем, но суть одна). Например:
Функция: Расчет количества корма
Сценарий: При вводе валидных параметров отображается правильный ответ
Когда я нахожусь на странице с формой
И ввожу возраст 5 лет
То мне отображается количество корма 500 г
Потом эти шаги реализуются в коде.
❓ Я фронтендер, зачем мне это надо
Умение тестировать свой код — очень жирный плюс для фронтендера, и вот почему:
PS В следующем посте расскажу об инструментах, которые мы используем для тестирования, и как у нас построен процесс.
Что такое TDD (test-driven development)
TDD существует с 1999 года и является методом разработки программного обеспечения, основанном на тестировании. В 2003 году американский разработчик Кент Бек «заново открыл» TDD и применил его как способ создания простых конструкций и внушающих доверие. На сегодняшний день, TDD – это процесс разработки программного обеспечения, использующий очень короткий цикл обратной связи, при котором разработчики:
Целью TDD является спецификация, а не валидация. Это один из способов продумать требования или дизайн до того, как функциональный код будет написан. TDD даёт возможность написать чистый код, который работает.
Оглавление
Развитие TDD
Подход TDD отличается от других методов тем, что он объединяет программирование с написанием тестов самим разработчиком. Эта концепция возобновляет всеобщее уважение к тестам, созданным программистом.

1990 год. В дисциплине тестирования преобладают методы «черного ящика», в частности, в форме инструментов тестирования «поймай и повтори».
1991 год. Независимое создание тестовой среды в Taligent поразительно похожей на SUnit.
1994 год. Кент Бек пишет тестовый скелет SUnit для Smalltalk.
1998 год. Статья об экстремальном программировании упоминает, что «мы обычно пишем тест в первую очередь».
С 1998 по 2002 год. Test First преобразован в Test Driven.
2000. Автоматизированные тесты – инновационные методы, разработанные в этот период.
2003 год. Публикация Кента Бека «Разработка через тестирование: на примере».
В 2006 году TDD превратился в признанную технику, которая стала поощрять дальнейшие инновации, такие как разработка на основе приемочных испытаний (ATDD) и развитие на основе поведения (BDD).
Что же такое Test Driven Development (TDD)?
Разработка через тестирование – это подход к программированию, при котором программирование должно вестись на основании тестирования, а не наоборот. При традиционном подходе к разработке программного обеспечения заказчик выдвигает требования к программе. Затем разработчик создает код, который соответствует критериям приемлемости пользовательской истории. Затем код будет объединен и протестирован тестировщиком в среде QA или SIT. Тестер может найти дефекты. В этом случае код отправляется на доработку.
Существует цикл: написать код, запустить тесты, исправить код. Test Driven Development переворачивает этот цикл с ног на голову. В нем говорится, что мы должны сначала создать тесты, затем написать код, после чего исправить код.
В Test Driven Development сначала пишется и запускается тест, затем пишется код (до тех пор, пока он не пройдёт тест), а затем код реорганизуется. Это называется рефакторинг.
Рефакторинг
Целью рефакторинга является чистый код, который идеально работает. Рефакторинг – это модификация исходного кода системы после незначительных изолированных изменений, не приводящих к изменению функциональности.
Функциональность может быть проверена во время рефакторинга путем многократного запуска тестов.
Рефакторинг может значительно улучшить читаемость кода, устранить дублирование, облегчить техническое обслуживание и расширение системы в будущем. Поскольку это небольшие, определенные и контролируемые изменения, их также можно автоматизировать с помощью инструментов рефакторинга, которые уже интегрированы во многие популярные среды разработки, что значительно повышает производительность труда разработчиков. Основной каталог модификаций – рефакторинг можно найти в отличной книге Мартина Фаулера «Рефакторинг».
Красный, зеленый, рефакторинг
Принцип работы в программировании TDD суммирует Кент Бек в хорошо запоминающийся фразу: красный, зеленый, рефакторинг. Названия цветов относятся к пользовательскому интерфейсу популярного автоматического запуска теста JUnit, где красная полоса указывает на то, что тест не пройден, а зеленая полоса указывает на то, что тест прошел успешно.
Это основа тестового программирования, подразумевающая, что весь процесс начинается с написания некоторых тестов, и они проваливаются (красный). Красная фаза заставляет задуматься о требованиях, прежде чем начать писать код. Благодаря этому наша система будет лучше продумана. Обнаруживаются несоответствия, которые помогают улучшить работу системы, прежде чем писать код.
Затем пишется код, пока тесты не будут пройдены (зеленый). На зеленой стадии добавляется минимальный объем производственного кода, необходимый для прохождения тестов. Затем код дорабатывается. То есть его улучшают, не влияя на поведение. И поскольку тесты уже готовы, то можно быстро их снова запустить и удостовериться, что рефакторинг не повлиял на функциональность.
Кент Бек, в eXtreme Programming (XP) (Beck 2000), определяет два простых правила для TDD:
Бек объясняет, как эти два простых правила генерируют сложное индивидуальное и групповое поведение:
Чтобы эффективно работать, разработчикам необходимо научиться писать эффективные модульные тесты. Бек считает, что хорошие юнит-тесты:
Какие существуют виды тестов?

Модульные тесты – тестирование приложения изнутри, с точки зрения программиста. Они тестируют код, выполняя тесты, проверяющие правильность работы библиотечных объектов / модулей / систем.
Цикличные – это непрерывное повторение создания модульных тестов, пока они не будут пройдены.
Эти типы тестов образуют Тестовую пирамиду.
Считается, что большинство тестов должны быть модульными, с меньшим количеством интеграционных тестов и ещё меньшим приемочных тестов. Google рекомендует соотношение примерно 70/20/10.
Инструменты
TDD должен сочетаться с хорошими инструментами. Необходима среда IDE, такая, как Eclipse с собственной поддержкой JUnit. Настоятельно рекомендуется использовать плагины для облегчения управления модульными тестами, такими как MoreUnit и Infinitest. Последний автоматически выполняет все модульные тесты при каждом изменении кода, что уменьшает циклы обратной связи, которые также закладывают основы для непрерывных модульных тестов. С другой стороны, использование шаблонов кода для модульных тестов является важной экономией времени в повторяющемся цикле TDD. На уровне кода для создания удобочитаемых и гибких бизнес-объектов необходим шаблон проектирования Builder.
Платформы и инструменты для тестов TDD для проектов PHP
Phpunit – это ориентированная на программиста платформа модульного тестирования для PHP, основанная на идее, что кодеры должны быстро находить ошибки в новых проектах без регрессии кода в других частях приложения. Используя Phpunit, можно легко проверить, работает ли каждый протестированный модуль так, как ожидалось.
Behat – это фреймворк BDD PHP с открытым исходным кодом, который использует «человеческие» предложения для запуска тестов программного обеспечения. Behat инструмент предложенный StoryBDD. Помогает определить описательные части, их потребности и вложенный в них смысл. Behat предлагает уникальный подход к тестированию.
Codeception – еще один надежный инструмент TDD для PHP. Codeception похож на PHPUnit и Behat, но все его тесты написаны на PHP, что делает процесс разработки более гибким. Во всех тестах Codeception можно использовать переменные и операторы, а также локаторы CSS и XPath.
Преимущества TDD
Уменьшает зависимость от отладки: поскольку вначале основное внимание уделяется написанию тестов, а затем – созданию кода, предназначенного для прохождения указанных тестов, многие разработчики считают, что жизненный цикл может значительно сократить потребность в отладке. Поскольку во время написания и кодирования теста требуется более глубокое понимание логических и функциональных требований, причину неудачного теста часто можно быстро распознать и устранить.
Анализирует пользовательский опыт: процесс первоначального осмысления и написания теста заставляет мозг программиста работать наоборот: сначала продумывать, как будет использоваться функция и как она может быть реализована, а только потом, как должен быть написан тест. Это побуждает учитывать особенности пользователя.
Сокращает общее время разработки: практика показывает, что уменьшается общее время разработки проекта по сравнению с традиционными методами написания кода. В то время как общее количество строк кода увеличивается (из-за тестов), частое тестирование исключает ошибки в процессе и выявляет существующие намного раньше, предотвращая возникновение проблем в дальнейшем.
Недостатки тест-ориентированной разработки
Не любит большой дизайн: поскольку разработчики пишут самый простой из возможных тестов, а затем проходят этот тест с помощью максимально простого кода, это приводит к серьезному дефициту возможностей в отношении общего дизайна функции или всего проекта. При использовании подобной практики слишком легко не заметить крупных ошибок, так как все внимание сосредоточено на мелочах.
Не подходит для всех: метод отлично зарекомендовал себя для работы с небольшими проектами или даже с небольшими компонентами или функциями крупных проектов. К сожалению, методика может давать сбои при применении к очень объёмным или сложным проектам. Написание тестов для сложной функции, которую программист ещё полностью не представляет, может быть трудным, и даже невозможным. Написание тестов – это хорошо, но если эти новые тесты не совсем точно соответствуют требованиям функции, они бесполезны (или даже могут активно препятствовать разработке). Более того, некоторые проекты, особенно те, которые используют устаревший код или сторонние системы, просто не поддаются практическим методам. Для них практически невозможно создать тесты, которые должным образом интегрируются с этими системами или с устаревшим кодом.
Требует дополнительных затрат времени: хотя время, затрачиваемое на предварительную генерацию тестов, экономится позднее в жизненном цикле разработки. Тем не менее, для подготовки и написания тестов требуется значительное время. Его многие разработчики предпочитают потратить на написание нового кода или рефакторинг существующего.
Когда применяется TDD
TDD подходит как для нового программного обеспечения, так и для устаревших систем. Для команды разработчиков, которая имеет дело с существующим устаревшим программным обеспечением, работа начинается исправлением ошибок. Хорошей практикой является то, что для каждой сообщаемой ошибки создаётся тест, который устраняет ошибку, а затем исправляется функциональность. После нескольких итераций команда разработчиков создаёт повторяемый рабочий тест для исправления ошибок. Применяя эту методологию к новым программным приложениям, следует обратить внимание на инструменты тестирования, используемые для стека технологий. Например, при работе в приложении Angular, которое обычно использует среду тестирования Jasmine для модульного тестирования, и при использовании для Angular CLI, модульные тесты создаются вместе с модулями кода. Методология TDD будет заключаться в следующем:
Измерение тестируемости с помощью покрытия кода
Для улучшения тестируемости кода, необходимо использование инструмента для оценки покрытия кода. Покрытие кода – это показатель, демонстрирующий процент кода, для которого написан модульный тест. Для расчета покрытия кода используют Istanbul. Выходные данные, предоставляемые Istanbul, дают оценку общего охвата тестированием и областей кода, которые нуждаются в улучшении тестирования. Этот показатель полезен, так как:
Однако, насколько бы эффективным не было покрытие кода, важно понимать, что это просто показатель. Написание хороших модульных тестов – это определяющее для рабочего код, и такие метрики не должны влиять на принятие важных решений.
Практика использования TDD
Важно отметить, что TDD не решает все проблемы. Существует много различных типов тестирования, необходимых для создания полной стратегии тестирования, включая приемочное тестирование. В TDD основное внимание уделяется одной единице кода за раз. У сложного программного приложения может быть много тысяч единиц кода и соответствующих тестов. Вот почему важно следить за тем, чтобы качество тестирования оставалось высоким при соблюдении методологии TDD. Тесты не могут быть отвергнуты в погоне за большей функциональностью или целесообразностью. Игнорирование тестирования создает риск того, что создание теста станет помехой для разработчиков.
Например, игнорирование неудачных тестов затрудняет определение фактического состояния приложения. Также важно выработать общий подход TDD у всех команд, вовлеченных в работу. Нужно потратить время на обсуждение природы и преимуществ метода TDD, а также убеждение в том, что использование TDD улучшит конечное программное обеспечение. В противном случае бизнес-руководство рассматривает написание тестов как деятельность, которая не способствует получению прибыли.
Резюме
Разработка через тестирование – это метод, который в настоящее время широко используется и становится все более популярным. Причина его популярности заключается в том, что усилия, необходимые для его освоения, не так велики, как для экстремального программирования, частью которого является TDD. Хотя у разработчика с самого начала должна быть дисциплина для написания и запуска тестов, без него не было бы программирования, управляемого тестами. Из-за своей природы метод может использоваться в сочетании с различными практиками разработки на более низком уровне (например, в течение одной итерации) и даже в более широком спектре проектов.
TDD подчеркивает важность эффективного и устойчивого подхода к тестированию. TDD также напрямую влияет на общее качество программного обеспечения. Это трюизм для разработки малых или больших систем, который часто упускается, чтобы получить новые функциональные возможности для производства. Качественное программное обеспечение создается, когда признается, что тестовый код должен получать столько же внимания и ресурсов, сколько и производственный код, поскольку они одинаково важны при разработке.
Что надо знать о TDD и BDD: как тесты помогают разработчикам работать в команде и понять заказчика
Java Developer в NIX
Вам знакома басня про лебедя, рака и щуку? Три совершенно разных существа тянули воз: лебедь пытался взлетать с ним, рак пятился с повозкой назад, а щука упорно тащила телегу на дно. Единства между ними не произошло, поэтому затея была обречена на провал — воз так и не сдвинулся с места.
Так аллегорично можно описать стандартный рабочий процесс, в котором заказчик хочет одно, руководитель проекта понимает задачу по-другому, а специалисты (дизайнеры, программисты, тестировщики) все делают по-своему… Иногда такие проекты доводят до конца. Однако зачастую они, как повозка из упомянутой басни, остаются на месте.
Чтобы в своей профессии вы не повторяли судьбу героев басни, были созданы методологии тестирования Test Driven Development (TDD) и Behavior Driven Development (BDD). Давайте разберемся, как они работают.
TDD и BDD: основные отличия модульного и интеграционного тестирования
Test Driven Development (TDD) — это разработка, основанная на тестировании. Предположим, вы получаете от заказчика запрос на добавление в разрабатываемый продукт нового функционала. Под этот запрос составляется техническая документация в виде тестов: в них согласованы и записаны новые требования, которые заказчик предъявляет к продукту.
Тестирование в TDD происходит через итерации (циклы) и соответствует такому порядку:
Все эти шаги TDD-разработки будут повторяться энное количество раз, пока специалисты не приведут код в соответствие с документацией и не удостоверятся в работоспособности новой функции.
Методология TDD относится к юнит-тестированию (модульному тестированию) и позволяет проверять отдельно взятые части продукта. Чаще всего TDD пишут сами разработчики, тесты реализуются в виде программного кода.
Но как протестировать не отдельный модуль продукта, а сложный сценарий с большим количеством условий и переменных?
В этом случае прибегают к использованию методологии Behavior Driven Development — разработке на основе поведения. В отличие от TDD, этот подход строится на написании нескольких пользовательских сценариев, под которые составляются тесты. BDD позволяет «предугадать», как поведет себя пользователь, используя продукт в соответствии с требованиями, которые записаны в технической документации. Порядок прохождения тестов схож с TDD. Единственное отличие — перед прохождением отдельных тестов формулируется ряд предварительных условий (сценариев), при которых они должны быть пройдены.
Сравненение BDD и TDD / TestLodge
Требования для BDD обычно составляет группа экспертов и не в виде программного кода, а словесно — на языке, понятном всем участникам проекта.
Behavior Driven Development относится к методам интеграционного тестирования. Оно позволяет понять, правильно ли взаимодействуют друг с другом отдельно взятые части программы.
Подход также эффективен в end-to-end-тестировании (Е2Е) и дает программистам представление о том, как функционирует вся разрабатываемая ими система. Получается, несмотря на то, что BDD и является расширением TDD-методологии, они имеют разное предназначение и реализуются разным набором инструментов.
В общем, мы друг друга поняли
Методологии BDD- и TDD- тестирования помогают достичь взаимопонимания между заказчиком продукта и всеми участниками, задействованными в его реализации.
Ч еткое следование прописанным заранее спецификациям позволяет избежать подводных камней в виде неоговоренных сценариев или разрозненной трактовки функционала продукта разными специалистами.
Весомое преимущество таких подходов в тестировании — отсутствие невалидных (недостоверных) сценариев. Каждый участник проекта еще на стадии проектирования может увидеть нереализуемые функции и рассказать об этом коллегам. Так можно исключить даже саму возможность создания неэффективного и бесполезного кода.
Еще один плюс — наличие технической документации. TDD и BDD предполагают четко структурированную документацию, которая помогает быстрее адаптироваться новичкам, зашедшим в проект, уже на этапе производства.
Разработка больше не зависит от человеческого фактора: чтобы понять, что происходило в проекте с момента его создания, достаточно открыть нужный файл.
Как составлять тесты?
Давайте подытожим кратким списком рекомендаций по составлению тестов:
Инструменты для реализации юнит-тестирования
Юнит-тестирование на Java осуществляется при помощи фреймворка JUnit. Он относится к семейству фреймворков xUnit и используется преимущественно для Test-Driven- и Behavior-Driven-разработки. На сегодня JUnit 5 — самая свежая версия фреймворка, которая совместима с версиями Java 8 и выше.
Это значит, что фреймворк поддерживает Stream API, лямбды, функциональные интерфейсы и массу других «плюшек», которые таит в себе Java 8+.
Характерным отличием JUnit 5 от своей предыдущей версии является возможность запускать сразу несколько раннеров для одного и того же класса (JUnit4 был способен выполнять только один класс-раннер). JUnit 5 состоит из трех отдельных пакетов, которые можно подключать независимо друг от друга:
JUnit 5 состоит из трех отдельных пакетов, которые можно подключать независимо друг от друга
Экстеншн-модели и аннотации в JUnit 5
Экстеншн-модель в JUnit Jupiter — это разновидность совершенно нового API, позволяющая расширять функционал отдельного теста и добавлять новые условия для работы с ним. Для работы с экстеншн-моделью существуют экстеншн-поинты.
Существует пять основных видов экстеншн-поинтов:
В JUnit пятой версии также расширен функционал Assertions API. Например, теперь вы сможете работать с методом assertAll, который построен на использовании лямбд. Он позволяет производить групповые проверки: каждая следующая проверка выполняется только в том случае, если предыдущая верна:
JUnit 5 также позволяет контролировать выполнение теста в зависимости от внешних условий. Вы можете выбирать ОС, на которой будете проводить тестирование, а также версию Java, на которой будет работать тест. Контролировать можно и то, при каких системных настройках будет запущен тест.
Также JUnit 5 помогает создавать свои собственные аннотации. Для этого необходимо указать @Target (ElementType.METHOD) для нового интерфейса и затем перечислить все аннотации, которые должны сработать при подключении вашей аннотации. Вот несколько примеров таких аннотаций:
Тестируй себя сам
Для любого разработчика очень важно уметь самостоятельно применять методы юнит-тестирования. Такой подход позволяет на ранних этапах уловить непонятные аспекты ТЗ до того, как будет реализован код. Помимо этого, TDD- и BDD- тестирование обеспечивает постоянную коммуникацию внутри команды: и исполнитель, и заказчик, и руководитель всегда будут находиться в одной плоскости понимания проекта. Именно в таком единстве всех участников процесса и заключается главное преимущество использования интеграционного и модульного тестирования.
Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.









