Перейти к основному содержимому

Тесты как часть культуры кода

Разработчику Тестировщику

Речь о качестве тестового кода, а не о «зачем тестировать». Хорошие тесты — такая же часть культуры, как имена и форматирование: они фиксируют модель 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 пустые — культура кода не растёт.


Краткий чек-лист

  1. Тест называется как сценарий: CancelOrder_WhenPaid_Throws.
  2. Один логический assert на поведение (допускаются несколько assert на один объект).
  3. Нет sleep и глобального state между тестами.
  4. Рефакторинг домена — тесты зелёные без правки ожиданий «потому что поменяли private».

Указатель тем — 13. Дальше: Исключения.


См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").