Взаимодействующие тесты (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(); }