# Unit Tests/TDD/BDD

## 1. What is the reason to write Unit Tests, how many? требования к юнит тестам

Цель тестирования — убедиться, что построенная система работает должным образом.

Advantages:

* Возможность нахождения багов как можно раньше (менее дорогостоящий фикс)
* Увеличение качества кода
* Дополнительная документация к коду
* Легкость рефакторинга и уверенность в изменении кода

Good Unit Test:

* Независимые
* Легко(просто) написаны, легко читаемый
* Быстрые
* Легкие к модификациям и расширению

JS testing tools:

* Jasmine
* Jest
* Mocha
* Ava
* Karma
* Chai
* Puppeteer

Правильный подход:

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKJg87IWeeytF3MA2IZ%2F-MKJhzkVo3yEuK6k1iId%2Fimage.png?alt=media\&token=b252130b-5b7c-4e51-a407-06a5a8311d2c)

Антипаттерн:

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKJg87IWeeytF3MA2IZ%2F-MKJiTNW6_TNbaJqSBhT%2Fimage.png?alt=media\&token=bb374386-2882-45bc-8865-ffb88135a4e3)

## 2. TDD vs BDD

### TDD

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

TDD состоит из цикла «red–green–refactor». \
\&#xNAN;***Этап Red***. Пишется тест, который представляет собой необходимое поведение системы, затем создается метод-заглушка, чтобы можно было быстро собрать проект. Тест компилируется, но не возвращает нужный результат. Появляется потребность в написании программы.&#x20;

***Этап Green***. Пишется минимальный код, который бы позволил тесту выполниться верно. В действительности это значит, что пишется кодбез структуры, без дизайна, без каких-либо шаблоновпроектирования. Теперь появляется потребность придать коду «красивый вид».

***Этап рефакторинга.*** Изменяется внешняя структура кода, без изменения его внешнего поведения. Это разделение на методы, добавлениеэлементовшаблона проектирования, созданиедополнительныхклассови т. д.Последовательность этаповцикла очень важна.&#x20;

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

Преимущества:

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

Недостатки

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

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKFCpIBB_XVjFKOHpt0%2F-MKFZXpZwOqH9LFg7pYL%2Fimage.png?alt=media\&token=02724f9f-f7ed-4244-af7d-fe5869562d1d)

### BDD

**BDD** (сокр. от [англ.](https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B3%D0%BB%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA) Behavior-driven development, дословно «разработка через поведение») — это методология разработки программного обеспечения, являющаяся ответвлением от [методологии разработки через тестирование](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) (TDD).

Плюсы:

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

Минусы:

* требует глубокого понимания большего количества концепций
* Создание сценариев и поддержка файлов требует много усилий и времени. Так что это не подходит для короткого проекта, который нам нужно выполнить за короткий промежуток времени. Но для долгосрочного проекта стоит использовать подход BDD.
* Нужна хорошая коммуникация между человеком, который разрабатывает код автоматизации, и человеком, который пишет файлы функций. Человеку, который пишет автоматизацию, нужны эти файлы и сценарии для разработки сценария автоматизации. Если у них нет взаимного понимания файлов, то разработать проект будет сложно.

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKFCpIBB_XVjFKOHpt0%2F-MKFbt_3CoqlfV8yUwbc%2Fimage.png?alt=media\&token=6dc62445-884f-4f4e-a6cb-3eb07c3302f7)

## 3. Unit Tests (FIRST)&#x20;

Каждый модульный тест должен обладать следующими характеристиками:

**Быстрота (Fast)**. Тесты должны выполняться быстро. Все мы знаем, что разработчики люди, а люди ленивы, поскольку эти выражения являются “транзитивными”, то можно сделать вывод, что люди тоже ленивы. А ленивый человек не захочет запускать тесты при каждом изменении кода, если они будут долго выполняться.

**Независимость (Independent).** Результаты выполнения одного теста не должны быть входными данными для другого. Все тесты должны выполняться в произвольном порядке, поскольку в противном случае при сбое одного теста каскадно “накроется” выполнение целой группы тестов.

**Повторяемость (Repeatable).** Тесты должны давать одинаковые результаты не зависимо от среды выполнения. Результаты не должны зависеть от того, выполняются ли они на вашем локальном компьютере, на компьютере соседа или же на билд-сервере. В противном случае найти концы с концами будет весьма не просто.

**Очевидность (Self-Validating).** Результатом выполнения теста должно быть булево значение. Тест либо прошел, либо не прошел и это должно быть легко понятно любому разработчику.  Не нужно заставлять людей читать логи только для того, чтобы определить прошел тест успешно или нет.

**Своевременность (Timely).** Тесты должны создаваться своевременно. Несвоевременность написания тестов является главной причиной того, что они откладываются на потом, а это “потом” так никогда и не наступает. Даже если вы и не будете писать тесты перед кодом (хотя этот вариант уже доказал свою жизнеспособность) их нужно писать как минимум параллельно с кодом.
