Книга Хорикова Владимира "Принципы юнит-тестирования"
1.3.3 про покрытие
Почему нельзя включить покрытие во внешних библиотеках? Зачем его там включать?
assertion free test (про мутационное тестирование можно написать)
Как нетрудно догадаться, ничего хорошего из этого не вышло. Разработчики стали искать
пути обойти эту систему. Многие пришли к интересному наблюдению: если обернуть все
тесты в блоки try/catch и не включать в них проверки (assertions), то такие тесты всегда
проходят успешно. Люди стали добавлять такие тесты ради достижения 100 % покрытия.
Не стоит и говорить, что эти тесты не приносили никакой пользы проекту. Более того,
они вредили, так как отнимали время у более продуктивной деятельности и повышали
затраты на сопровождение проекта.
2.3.1 Тесты не должны проверять единицы кода (units of code). Вместо этого они должны про-
верять единицы поведения (units of behavior) — нечто имеющее смысл для предметной об-
ласти, а в идеале — нечто такое, полезность которого будет понятна бизнесу. Количество
классов, необходимых для реализации такой единицы поведения, не имеет значения.
Тест может охватывать как несколько классов, так и только один класс или даже всего
один маленький метод.
Неявно автор подразумевает что все пишут только на языках с поддержкой OOP. Как будто процедурный и функциональные стили е существуют.
ПРИМЕЧАНИЕ
Одним из факторов успеха парадигмы объектно-ориентированного программирования
(ООП) стала именно улучшенная читаемость кода. В ООП вы тоже можете структурировать
свой код так, чтобы он читался как рассказ.
4.1. Четыре аспекта хороших юнит-тестов
Хороший юнит-тест должен обладать следующими четырьмя атрибутами:
защита от багов;
устойчивость к рефакторингу;
быстрая обратная связь;
простота поддержки.
Напомню, что весь код, включая код тестов, является обязательством, а не активом.
Рис. 4.9.
Точное соотношение между типами тестов будет разным для разных команд и про-
ектов. Но в общем случае должно сохраняться соотношение пирамиды: сквозные
тесты составляют меньшинство; юнит-тесты — большинство; интеграционные тесты
лежат где-то в середине.
Если тест
не удается связать с бизнес-требованием, это является признаком хрупкости теста. Единственное исключение составляют тесты, содержащие служебный код с высокой
алгоритмической сложностью (подробнее об этом в главе 7).
Три стиля юнит-тестирования
Как я сказал во введении, существуют три стиля юнит-тестирования:
проверка выходных данных;
проверка состояния;
проверка взаимодействий.
6.3.1. Что такое функциональное программирование?
Часть III Интеграционное тестирование
Соотношение между юнит- и интеграционными тестами зависит от особенностей
проекта, но общее правило выглядит так: проверьте как можно больше пограничных
случаев бизнес-сценария юнит-тестами; используйте интеграционные тесты для
покрытия одного позитивного пути, а также всех граничных случаев, которые не
покрываются юнит-тестами. Перемещение основной части работы в юнит-тесты помогает удерживать затра-
ты на сопровождение на низком уровне. В то же время наличие одного или двух интеграционных тестов на бизнес-сценарий гарантирует правильность вашей систе-
мы в целом. Это правило формирует соотношение между количеством юнит- и ин-
теграционных тестов, показанное на рис. 8.2 (как упоминалось в главе 2, сквозные
тесты образуют подмножество интеграционных тестов). Пирамида тестирования может принимать разные формы в зависимости от слож-
ности проекта. В простых приложениях объем кода в четверти доменной модели
и алгоритмов минимален. В результате тесты образуют прямоугольник вместо пи-
рамиды, с равным количеством юнит- и интеграционных тестов (рис. 8.3). В самых
тривиальных случаях юнит-тестов может вообще не быть.
СОВЕТ
Написание кода — дорогостоящий способ решения задач. Чем меньше кода требует
решение и чем проще этот код, тем лучше.
Интеграционным тестом является любой тест, который не является юнит-тестом.
10.1.1. Хранение базы данных в системе контроля версий
НАРУШЕНИЕ ЦЕЛОСТНОСТИ ДАННЫХ В НЕРЕЛЯЦИОННЫХ
БАЗАХ ДАННЫХ
Избежать нарушений целостности данных при использовании реляционной базы дан-
ных несложно: все популярные реляционные базы данных предоставляют атомарные
обновления, которые могут охватывать любое количество строк. Но как добиться того
же уровня защиты с нереляционными базами данных — например, MongoDB?
Проблема многих нереляционных баз данных — отсутствие транзакций в классическом
смысле; атомарность обновлений гарантируется только в пределах одного документа.
Если бизнес-операция затрагивает несколько документов, появляется риск нарушения
целостности данных. (В нереляционных базах данных документ является эквивалентом
строки.)