Взаимодействующие тесты (Interacting Tests)

Тесты в одном сьюте изменяют общее состояние — статическое поле, кэш, запись в БД, файл — и это состояние незаметно переходит к следующим тестам. Результат зависит от порядка выполнения тестов.

Симптомы

  • Статические поля (static Map, static List) изменяются в тест-методах
  • Тест A проходит всегда, тест B иногда падает — в зависимости от того, выполнялся ли тест A до него
  • При запуске всего сьюта — зелёный; при запуске только нескольких тестов — красный
  • Нет @BeforeEach/@AfterEach с очисткой общего состояния
  • Отличие от Test Interdependency (#5): нет явного @Order, зависимость случайная и неочевидная

Причины возникновения

  • Использование статических утилит или кэшей в тестируемом коде без механизма сброса
  • Нет изоляции между тестами на уровне архитектуры (синглтоны, глобальный state)
  • Забытый @BeforeEach после рефакторинга
  • Тесты писались и работали по одному; проблема появилась при добавлении второго теста

Почему это проблема

  • Случайные падения: порядок тестов в JUnit не гарантирован — тесты падают по непредсказуемым причинам
  • Трудная диагностика: тест B упал, но проблема в тесте A — связь неочевидна
  • Нельзя запускать параллельно: несколько потоков одновременно изменяют общий state
  • Ложная надёжность: при локальном запуске зелёный, на CI в другом порядке — красный

Решение

Сброс shared state в @BeforeEach или @AfterEach:

// ❌ статический кэш не очищается между тестами
@Test void testA() { ProductCache.put("X", product); }
@Test void testB() { assertThat(ProductCache.size()).isEqualTo(0); } // падает

// ✅ явная очистка перед каждым тестом
@BeforeEach
void clearCache() { ProductCache.clear(); }