Условная логика в тесте (Conditional Test Logic)
Тест содержит операторы if, switch или циклы for/while. В зависимости от условий тест проверяет разное поведение — или не проверяет ничего вовсе.
Симптомы
-
if,else if,switchвнутри@Test-метода -
for (Item item : list) { assertTrue(...) }— если список пустой, ни один assert не выполнится - Тест проверяет одно поведение при одних данных и другое при других
- Тест всегда зелёный, даже когда список пуст или коллекция не содержит нужных элементов
Причины возникновения
- Попытка охватить несколько сценариев одним тестом через ветвление
- Копирование стиля продакшн-кода в тесты — «здесь тоже нужен if»
- Незнание параметризованных тестов (
@ParameterizedTest) как альтернативы - Стремление написать «универсальный» тест, работающий при разных данных
Почему это проблема
-
Непредсказуемость: тест может не выполнить ни одного
assertи при этом быть зелёным - Разная логика при разных данных: сложно понять, что именно проверяется и в каком сценарии
- Скрытые ошибки: условие никогда не выполняется в CI — тест зелёный, дефект не обнаружен
- Трудно читать и поддерживать: нужно прослеживать все ветки в уме
Решение
Конкретные сценарии без ветвлений, при необходимости — @ParameterizedTest:
// ❌ for + if — может не выполнить ни один assert
for (Product p : catalog.getDiscounted()) {
if (p.getCategory().equals("ELECTRONICS")) assertTrue(p.getDiscount() >= 10);
else assertTrue(p.getDiscount() >= 5);
}
// ✅ явный сценарий + проверка непустоты перед итерацией
@Test
void electronicsDiscountIsAtLeast10Percent() {
assertThat(catalog.getDiscounted())
.filteredOn(p -> p.getCategory().equals("ELECTRONICS"))
.isNotEmpty()
.allMatch(p -> p.getDiscount() >= 10);
}