Принципы юнит-тестирования

Принципы юнит-тестирования

Принципы юнит-тестирования
Автор: Хориков Владимир
Дата выхода: 2021
Издательство: Питер
Количество страниц: 320
Размер файла: 1.8 MB
Тип файла: PDF
Добавил: codelibs
 Проверить на вирусы

Предисловие к русскому изданию....14

Предисловие к оригинальному изданию....15

Благодарности....16

О книге....17

Для кого написана эта книга....17

Структура книги....18

О коде....19

Форум для обсуждения книги....19

Об авторе....19

Иллюстрация на обложке....20

От издательства....20

Часть I. Общая картина....21

Глава 1. Цель юнит-тестирования....22

1.1. Текущее состояние дел в юнит-тестировании....23

1.2. Цель юнит-тестирования....24

1.2.1. В чем разница между плохими и хорошими тестами?....26

1.3. Использование метрик покрытия для оценки качества тестов....28

1.3.1. Метрика покрытия code coverage....28

1.3.2. Branch coverage....30

1.3.3. Проблемы с метриками покрытия....31

1.3.4. Процент покрытия как цель....34

1.4. Какими должны быть успешные тесты?....35

1.4.1. Интеграция в цикл разработки....35

1.4.2. Проверка только самых важных частей кода....35

1.4.3. Максимальная защита от багов при минимальных затратах на сопровождение....36

1.5. Что вы узнаете из книги....37

Итоги....38

Глава 2. Что такое юнит-тест?....40

2.1. Определение юнит-теста....40

2.1.1. Вопрос изоляции: лондонская школа....41

2.1.2. Проблема изоляции: классический подход....47

2.2. Классическая и лондонская школы юнит‑тестирования....50

2.2.1. Работа с зависимостями в классической и лондонской школе....51

2.3. Сравнение классической и лондонской школ юнит‑тестирования....54

2.3.1 Юнит-тестирование одного класса за раз....55

2.3.2. Юнит-тестирование большого графа взаимосвязанных классов....56

2.3.3. Выявление точного местонахождения ошибки....57

2.3.4. Другие различия между классической и лондонской школой....57

2.4. Интеграционные тесты в двух школах....58

2.4.1. Сквозные (end-to-end) тесты как подмножество интеграционных тестов....60

Итоги....62

Глава 3. Анатомия юнит-теста....64

3.1. Структура юнит-теста....65

3.1.1. Паттерн AAA....65

3.1.2. Избегайте множественных секций arrange, act и assert....66

3.1.3. Избегайте команд if в тестах....67

3.1.4. Насколько большой должна быть каждая секция?....68

3.1.5. Сколько проверок должна содержать секция проверки?....70

3.1.6. Нужна ли завершающая (teardown) фаза?....71

3.1.7. Выделение тестируемой системы....71

3.1.8. Удаление комментариев «arrange/act/assert» из тестов....72

3.2. Фреймворк тестирования xUnit....72

3.3. Повторное использование тестовых данных между тестами....74

3.3.1. Сильная связность (high coupling) между тестами как антипаттерн....75

3.3.2. Использование конструкторов в тестах ухудшает читаемость....76

3.3.3. Более эффективный способ переиспользования тестовых данных....76

3.4. Именование юнит-тестов....78

3.4.1. Рекомендации по именованию юнит-тестов....80

3.4.2. Пример: переименование теста в соответствии с рекомендациями....80

3.5. Параметризованные тесты....82

3.5.1. Генерирование данных для параметризованных тестов....85

3.6. Использование библиотек для дальнейшего улучшения читаемости тестов....86

Итоги....88

Часть II. Обеспечение эффективной работы ваших тестов....89

Глава 4. Четыре аспекта хороших юнит-тестов....90

4.1. Четыре аспекта хороших юнит-тестов....91

4.1.1. Первый аспект: защита от багов....91

4.1.2. Второй столп: устойчивость к рефакторингу....92

4.1.3. Что приводит к ложным срабатываниям?....94

4.1.4. Тестирование конечного результата вместо деталей имплементации....98

4.2. Связь между первыми двумя атрибутами....99

4.2.1. Максимизация точности тестов....100

4.2.2. Важность ложных и ложноотрицательных срабатываний: динамика....101

4.3. Третий и четвертый аспекты: быстрая обратная связь и простота поддержки....103

4.4. В поисках идеального теста....103

4.4.1. Возможно ли создать идеальный тест?....104

4.4.2. Крайний случай №1: сквозные (end-to-end) тесты....105

4.4.3. Крайний случай № 2: тривиальные тесты....106

4.4.4. Крайний случай №3: хрупкие тесты....106

4.4.5. В поисках идеального теста: результаты....108

4.5. Известные концепции автоматизации тестирования....111

4.5.1. Пирамида тестирования....111

4.5.2. Выбор между тестированием по принципу «черного ящика» и «белого ящика»....114

Итоги....115

Глава 5. Моки и хрупкость тестов....117

5.1 Отличия моков от стабов....118

5.1.1 Разновидности тестовых заглушек....118

5.1.2. Мок-инструмент и мок-тестовая-заглушка....120

5.1.3. Не проверяйте взаимодействия со стабами....121

5.1.4. Использование моков вместе со стабами....122

5.1.5. Связь моков и стабов с командами и запросами....123

5.2. Наблюдаемое поведение и детали имплементации....124

5.2.1. Наблюдаемое поведение — не то же самое, что публичный API....125

5.2.2. Утечка деталей имплементации: пример с операцией....126

5.2.3. Хорошо спроектированный API и инкапсуляция....129

5.2.4. Утечка деталей имплементации: пример с состоянием....130

5.3. Связь между моками и хрупкостью тестов....132

5.3.1. Определение гексагональной архитектуры....132

5.3.2 Внутрисистемные и межсистемные взаимодействия....136

5.3.3. Внутрисистемные и межсистемные взаимодействия: пример....138

5.4. Еще раз о различиях между классической и лондонской школой юнит-тестирования....141

5.4.1. Не все внепроцессные зависимости должны заменяться моками....142

5.4.2. Использование моков для проверки поведения....144

Итоги....144

Глава 6. Стили юнит-тестирования....147

6.1. Три стиля юнит-тестирования....148

6.1.1. Проверка выходных данных....148

6.1.2. Проверка состояния....149

6.1.3. Проверка взаимодействий....150

6.2. Сравнение трех стилей юнит-тестирования....151

6.2.1. Сравнение стилей по метрикам защиты от багов и быстроте обратной связи....152

6.2.2. Сравнение стилей по метрике устойчивости к рефакторингу....152

6.2.3. Сравнение стилей по метрике простоты поддержки....153

6.2.4. Сравнение стилей: результаты....156

6.3. Функциональная архитектура....157

6.3.1. Что такое функциональное программирование?....157

6.3.2 Что такое функциональная архитектура?....161

6.3.3. Сравнение функциональных и гексагональных архитектур....163

6.4. Переход на функциональную архитектуру и тестирование выходных данных....164

6.4.1. Система аудита....165

6.4.2. Использование моков для отделения тестов от файловой системы....167

6.4.3. Рефакторинг для перехода на функциональную архитектуру....170

6.4.4. Потенциальные будущие изменения....176

6.5. Недостатки функциональной архитектуры....177

6.5.1. Применимость функциональной архитектуры....177

6.5.2. Недостатки по быстродействию....179

6.5.3. Увеличение размера кодовой базы....179

Итоги....180

Глава 7. Рефакторинг для получения эффективных юнит-тестов....182

7.1. Определение кода для рефакторинга....183

7.1.1. Четыре типа кода....183

7.1.2. Использование паттерна «Простой объект» для разделения переусложненного кода....187

7.2. Рефакторинг для получения эффективных юнит‑тестов....190

7.2.1. Знакомство с системой управления клиентами....190

7.2.2. Версия 1: преобразование неявных зависимостей в явные....192

7.2.3 Версия 2: уровень сервисов приложения....193

7.2.4. Версия 3: вынесение сложности из сервисов приложения....195

7.2.5. Версия 4: Новый класс Company....197

7.3. Анализ оптимального покрытия юнит-тестов....200

7.3.1. Тестирование слоя предметной области и вспомогательного кода....200

7.3.2. Тестирование кода из трех других четвертей....201

7.3.3. Нужно ли тестировать предусловия?....202

7.4. Условная логика в контроллерах....203

7.4.1. Паттерн «CanExecute/Execute»....205

7.4.2. Использование доменных событий для отслеживания изменений доменной модели....208

7.5. Заключение....212

Итоги....214

Часть III. Интеграционное тестирование....217

Глава 8. Для чего нужно интеграционное тестирование?....218

8.1. Что такое интеграционный тест?....219

8.1.1. Роль интеграционных тестов....219

8.1.2. Снова о пирамиде тестирования....220

8.1.3. Интеграционное тестирование и принцип Fail Fast....222

8.2. Какие из внепроцессных зависимостей должны проверяться напрямую....224

8.2.1. Два типа внепроцессных зависимостей....224

8.2.2. Работа с управляемыми и неуправляемыми зависимостями....225

8.2.3. Что делать, если вы не можете использовать реальную базу данных в интеграционных тестах?....226

8.3. Интеграционное тестирование: пример....227

8.3.1. Какие сценарии тестировать?....228

8.3.2. Классификация базы данных и шины сообщений....229

8.3.3. Как насчет сквозного тестирования?....229

8.3.4. Интеграционное тестирование: первая версия....231

8.4. Использование интерфейсов для абстрагирования зависимостей....232

8.4.1. Интерфейсы и слабая связность....232

8.4.2. Зачем использовать интерфейсы для внепроцессных зависимостей?....233

8.4.3. Использование интерфейсов для внутрипроцессных зависимостей....235

8.5. Основные приемы интеграционного тестирования....235

8.5.1. Явное определение границ модели предметной области....235

8.5.2. Сокращение количества слоев....236

8.5.3. Исключение циклических зависимостей....237

8.5.4. Использование нескольких секций действий в тестах....240

8.6. Тестирование функциональности логирования....241

8.6.1. Нужно ли тестировать функциональность логирования?....241

8.6.2. Как тестировать функциональность логирования?....243

8.6.3. Какой объем логирования можно считать достаточным?....248

8.6.4. Как передавать экземпляры логеров?....249

8.7. Заключение....250

Итоги....250

Глава 9. Рекомендации при работе с моками....254

9.1. Достижение максимальной эффективности моков....254

9.1.1. Проверка взаимодействий на границах системы....257

9.1.2. Замена моков шпионами....261

9.1.3. Как насчет IDomainLogger?....263

9.2. Практики мокирования....263

9.2.1. Моки только для интеграционных тестов....264

9.2.2. Несколько моков на тест....264

9.2.3. Проверка количества вызовов....265

9.2.4. Используйте моки только для принадлежащих вам типов....265

Итоги....267

Глава 10. Тестирование базы данных....268

10.1. Предусловия для тестирования базы данных....269

10.1.1. Хранение базы данных в системе контроля версий....269

10.1.2. Справочные данные являются частью схемы базы данных....270

10.1.3. Отдельный экземпляр для каждого разработчика....271

10.1.4. Развертывание базы данных на основе состояния и на основе миграций....271

10.2. Управление транзакциями....274

10.2.1 Управление транзакциями в рабочем коде....274

10.2.2. Управление транзакциями в интеграционных тестах....282

10.3. Жизненный цикл тестовых данных....284

10.3.1. Параллельное или последовательное выполнение тестов?....284

10.3.2. Очистка данных между запусками тестов....285

10.3.3. Не используйте базы данных в памяти....287

10.4. Переиспользование кода в секциях тестов....287

10.4.1. Переиспользование кода в секциях подготовки....288

10.4.2. Переиспользование кода в секциях действий....290

10.4.3. Повторное использование кода в секциях проверки....291

10.4.4. Не создает ли тест слишком много транзакций?....292

10.5. Типичные вопросы при тестировании баз данных....293

10.5.1. Нужно ли тестировать операции чтения?....294

10.5.2. Нужно ли тестировать репозитории?....294

10.6. Завершение....296

Итоги....297

Часть IV. Антипаттерны юнит-тестирования....299

Глава 11. Антипаттерны юнит‑тестирования....300

11.1. Юнит-тестирование приватных методов....300

11.1.1. Приватные методы и хрупкость тестов....301

11.1.2. Приватные методы и недостаточное покрытие....301

11.1.3. Когда тестирование приватных методов допустимо....302

11.2. Раскрытие приватного состояния....304

11.3. Утечка доменных знаний в тесты....306

11.4. Загрязнение кода....307

11.5. Мокирование конкретных классов....310

11.6. Работа со временем....313

11.6.1. Время как неявный контекст....313

11.6.2. Время как явная зависимость....314

11.7. Завершение....315

Итоги....315

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

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

В этой книге:

  • Универсальные рекомендации по оценке тестов.
  • Тестирование для выявления и исключения антипаттернов.
  • Рефакторинг тестов вместе с рабочим кодом.
  • Использование интеграционных тестов для проверки всей системы.

Похожее:

Список отзывов:

Нет отзывов к книге.