Всем привет!
На дворе 2 декабря, и мы продолжаем рождественский календарь постом про злоупотребление селенидом.
Как надругаться над Селенидом
(и почему это у многих вызывает трудности)
Я часто получаю жалобу, что у людей не ловится ошибка вот в таком коде:
try {
$(".banner").shouldBe(visible);
$(".banner .close").click();
}
catch (Exception e) {
// System.out.println("Элемент не найден - значит, баннер в этот раз не появился");
}
Этот тест хочет проверить, появился ли рекламный баннер. Но не сразу, а немножко подождать: вдруг баннер появится с задержкой. И если появился, надо его закрыть.
Почему это плохой тест?
Потому, что он медленный.
В большинстве случае баннер не появится, и тест будет ждать 4 секунды (или какой у вас таймаут).
Это ужасно. Вы профессионалы или кто? Ваша цель - сделать тесты быстрыми и надёжными. Иначе чем вы отличаетесь от обезьяны?
Почему это очень плохой тест?
Потому, что он нестабильный.
Иногда баннер будет появляться как раз на истёке 4 секунд. Тест решит, что баннера нет, и пойдёт дальше, а тут оп! - и выскочит баннер. И вы получаете “моргающий” тест.
Почему это очень-очень плохой тест?
Потому, что он не тестирует сам баннер.
-
Представьте себе, что за время прогона тестов баннер так ни разу и не появился. Все тесты зелёные. А у реальных пользователей баннер появляется, и как раз тогда случается ошибка. И всё крэшится. Пользователи жалуются и обрушивают рейтинг вашего приложения.
А ваши тесты зелёные. -
Или наоборот, во время прогона тестов баннер появляется постоянно. Ну вот так сложилось в тестовой среде. А у реальных пользователей баннер появляется редко, и как раз без баннера случается ошибка. Всё крэшится. Пользователи жалуются и обрушивают рейтинг вашего приложения.
А ваши тесты зелёные.
Что же делать?
Очевидно, что у вас должно быть как минимум два теста:
- Случай, когда баннер выскакивает, и
- Случай, когда баннер не выскакивает.
Значит, у вас должна быть возможность как-то управлять показом баннера. Либо через “ручку” (api) тестируемого приложения, либо через какую-то админку, либо запуском SQL в базе. Как угодно. Если такой ручки нет, надо пойти договориться с разработчиками.
Только не надо мне говорить, что договориться не получится. Вы профессионалы или кто?
Если не получится, то стирайте весь этот тест. Не получилось так не получилось.
Подробнее про ручки и управление тестовой средой см. в докладе Arrange, mazafaka!
И наконец, на десерт:
Почему ошибка не ловится?
Вы уже догадались, почему ошибка не ловится?
Всё дело в иерархии исключений в Java. Базовый класс не Exception
, а Throwable
.
Throwable
Exception
RuntimeException
WebDriverException
Error
AssertionError
UIAssertionError
ElementShould
Именно поэтому, когда вы ловите catch (Exception e)
, мимо вас пролетают все подклассы Error
, в том числе все селенидовские ошибки.
“Ну отлично, буду ловить catch (Error e)
” - решите вы. НЕТ! Прошу вас, НЕТ!
Читаем javadoc к классу java.lang.Error
:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.
Что теперь?
Я надеюсь, вы перестанете ловить ошибки в тестах. Тесты для того и созданы, чтобы сообщать об ошибках, а не ловить их.
Надеюсь, вы посмотрите Arrange, mazafaka! и возьмёте управление тестовой средой под свой контроль.
И решите для себя, тварь вы дрожащая, или право имеете?
ru.selenide.org
02.12.19