Как обрабатывать исключения в Java: прокидывать дальше или возвращать пустой список
Что проверяют
Различаете ли вы «данных нет» и «данные не удалось получить» и понимаете ли, чем эта разница оборачивается в автотестах. Для QA-инженера это вопрос о том, не прячет ли ваш фреймворк падения. Следом могут спросить про checked и unchecked исключения и про то, как это выглядит в отчёте.
Как отвечать
Правило простое. Пустой список означает нормальный результат: поиск ничего не нашёл, у пользователя нет заказов. Исключение означает, что метод не выполнил работу: сервис не ответил, JSON не разобрался, истёк таймаут. Смешивать эти случаи нельзя.
В тестовом коде это особенно важно:
- API-клиент и шаги: метод
getOrders(), который ловитIOExceptionи возвращаетList.of(), делает зелёным тест «после удаления заказов нет», даже когда сервис лежит. Такой метод должен падать; - checked-исключения: если сигнатура мешает, заворачивайте в unchecked с сохранением причины, например
throw new UncheckedIOException("не получили заказы", e), или в своё исключение сcause; - отчёт: в Allure тест с
AssertionErrorпомечается как failed, а с любым другим исключением как broken. Это полезный сигнал: failed говорит о баге продукта, broken о проблеме окружения или самого теста; - пример из Selenium:
findElementsвозвращает пустой список, если ничего не найдено, аfindElementбросаетNoSuchElementException. Выбирают по смыслу проверки: для «элемента нет» подходит первый, для «элемент обязан быть» второй.
Пустой список возвращайте неизменяемым: List.of() или Collections.emptyList(). А null вместо списка хуже обоих вариантов: он перекладывает проверку на каждого вызывающего и заканчивается NullPointerException далеко от места ошибки.
Где спотыкаются
Пишут catch (Exception e) { e.printStackTrace(); } и возвращают пустой результат. Тест проходит, лог никто не читает, баг уезжает в прод.
Заворачивают исключение без причины: throw new RuntimeException("ошибка"). Стек исходной проблемы теряется, и разбирать падение приходится вслепую.
Проверяют отсутствие элемента через findElements при большом неявном ожидании. Метод честно ждёт весь таймаут, и каждая такая проверка добавляет секунды к прогону.