Тесты как часть культуры кода
Речь о качестве тестового кода, а не о «зачем тестировать». Хорошие тесты — такая же часть культуры, как имена и форматирование: они фиксируют модель MAPPER и страхуют рефакторинг.
Углублённый курс — тестирование, юнит-тесты, white-box.
Не тестируйте приватные методы
Приватное — деталь реализации. Тестируйте публичный контракт класса или use case. Если приватный метод настолько сложен, что «хочется теста» — вынесите его в отдельный класс с явным API.
Исключение — не «тест private через reflection», а пересмотр границ.
Утверждения с содержанием
| Плохо | Лучше |
|---|---|
assertTrue(result) | assertEquals(ExpectedDiscount.TEN_PERCENT, order.discount()) |
assertNotNull(x) без проверки полей | Сравнение значимых полей value object |
Сравнение double на == | Допуск или BigDecimal / decimal |
Добавляйте описания в assert-сообщениях; заменяйте общие assertTrue на конкретные матчеры.
Моки и реальные объекты
Не мокайте всё подряд. Value objects, чистые функции, in-memory репозитории часто проще и стабильнее моков. Мок уместен на границе (HTTP, БД, почта).
Чрезмерные моки делают тест хрупким: любой рефакторинг внутренностей ломает 20 тестов, хотя поведение не менялось.
Flaky-тесты
Flaky — тест, который то проходит, то падает без изменения кода. Причины:
- зависимость от времени (
DateTime.Now, sleep); - порядок выполнения;
- общий mutable state;
- сеть и race.
Лечение: инъекция часов, изоляция данных, фикстуры, отказ от Thread.Sleep как «синхронизации».
Тестовые данные
- Реалистичные имена и значения — проще читать падение.
- Минимум лишнего в arrange — один сценарий на тест.
- Не ломать инкапсуляцию ради теста — фабрики в test scope, не
public set«для тестов».
Тест на каждый merge (CI) — культура команды, не личный ритуал.
Тесты вместо комментариев
Если комментарий объясняет поведение, часто лучше характеризационный тест (легаси). Комментарий устаревает; тест в CI — нет.
Связь с цикломатической сложностью
Чем выше M у функции, тем больше независимых сценариев нужно покрыть (статья 2). Если покрытие гонят «ради процента», а assert пустые — культура кода не растёт.
Краткий чек-лист
- Тест называется как сценарий:
CancelOrder_WhenPaid_Throws. - Один логический assert на поведение (допускаются несколько assert на один объект).
- Нет
sleepи глобального state между тестами. - Рефакторинг домена — тесты зелёные без правки ожиданий «потому что поменяли private».
Указатель тем — 13. Дальше: Исключения.
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Именование, форматирование, комментарии, документация в коде и базовые принципы читаемости — практики, которые команда договаривается соблюдать каждый день. Цикломатическая сложность — одна из наиболее устойчиво применяемых метрик статического анализа программного кода, призванная количественно оценивать логическую структуру исполняемого модуля. Правило MAPPER (Model Abstract Partial Programmable Explaining Reality) — как сопоставлять реальность и код один к одному. Богатые объекты предметной области, value objects вместо string/int и антипаттерны DTO-оргии. const, иммутабельность, ленивая инициализация и побочные эффекты в читаемом коде. Разделение «что» и «как», итерации, магические числа, callback hell и явные ошибки. Меньше if и switch, отказ от null, быстрый провал и полиморфизм вместо флагов. Singleton, god object, shotgun surgery, feature envy и глобальное состояние — симптомы и приёмы рефакторинга. Мёртвый код, лишние абстракции, отключённые предупреждения и отложенный рефакторинг. Пустые catch, исключения как goto, узкие try и сообщения для пользователя. Краткие итоги раздела "Культура кода". Вопросы перед отправкой кода в репозиторий — именование, принципы, тесты, ревью и безопасность. Ответы ищите в статьях раздела.Культура написания и поддержки кода
Цикломатическая сложность и читаемость кода
MAPPER — модель кода и предметная область
Анемичные модели и примитивная одержимость
Изменяемость, побочные эффекты и неизменяемые данные
Декларативный код — что и как
Условия, null и явные контракты
Связанность, глобалы и запахи модульности
YAGNI, быстрый провал и техдолг в коде
Исключения и обработка ошибок в читаемом коде
Итоги
Чек-лист самопроверки