Почему нестабильны UI-тесты. А на самом деле?

Все вы знаете, что UI-тесты бывают нестабильны.

Почему? Недавно мне попалась статья "Автоматизация тестирования: как избежать распространенных ошибок", которая среди прочего, даёт ответ на этот вопрос. У приведённого ответа есть преимущества и недостатки. Преимущество заключается в его простоте. Досадный недостаток - в том, что этот ответ абсолютно, просто таки в корне, неверен.

Автоматизация_тестирования__как_избежать_распространенных_ошибок___DOU

 

Давайте же разбираться, почему этот ответ неверен, и почему на самом деле UI-тесты, как правило, нестабильны.

Возьмём для примера довольно типичный для данной категории автоматизированный тест, использующий библиотеку основанную на фреймворке Selenium WebDriver. Запуск данного теста затрагивает, помимо нескольких слоёв самого приложения также: браузер, драйвер браузера (WebDriver),  (core) библиотеку Selenium, кастомную библиотеку, основанную на Seleniume (Selenide, JDI, Protractor, ваш собственный велосипед) ну и собственно код вашего теста (см. рисунок), причем неоднократно.Untitled_3
Проблема в том, что каждый из этих слоёв пирога - софт, а в софте, как вы знаете, случаются ошибки. Например:

  • Ошибки в вашем тестовом коде (окей, тут ничем не хуже и не лучше, чем в других типах тестов)
  • Ошибки в вашем (или чужом) фреймворке для автоматизации (когда, функция работает не так, как вы считаете что она работает)
  • Ошибки в Selenium Core (редко, но случаются)
  • Ошибки в драйверах браузера (WebDriver) - по моему мнению в среднем по больнице тут находится наибольшее количество ошибок, которые приводят к тем неприятным сбоям в тестах, которые мы не можем объяснить
  • Ошибки в браузере (некоторые их них мы и хотим обнаружить своевременно, с помощью автотестов)
    Прочие факторы негативно влияющие на  нестабильность UI-тестов:
  • UI-тесты частенько выполняют целые сценарии состоящие из нескольких проходов (зачастую - многих десятков) через слои внутри одного теста.
  • Для Web тестирования мы пытаемся использовать один и тот же код тестов для разных браузеров, в то же время слои Framework и BrowserDriver могут при это содержать различные ошибки, требующие различных "workaround"-ов.
  • JS-Frontend в Web: обработчики ввода не готовы принимать данные с высокой скоростью WebDriver-a, зачастую работают асинхронно, провоцируя ошибки из-за порядка выполнения, которые ужасно сложно находить и отлаживать, потому что вручную все обработчики успевают отработать целиком из-за низкой скорости ввода.
  • Как известно, малые вероятности ошибок перемножаются, поэтому, к примеру, если один UI тест проходит через 10 слоёв пирога 20 раз (всего 200 проходов) и вероятность словить ошибку в каждом слое составляет всего 0,1% (один раз из 1000) за проход, суммарная вероятность ошибки будет около 18% (0,999 в степени  200), т.е. почти каждый пятый тест будет падать.

    На практике, вероятность ошибок неодинакова в каждом слое, и наверное значительно меньше указанной, но закон больших чисел непобедим, и его следствия знают все, кто серьёзно занимался автоматизацией. После написания первых 2 тестов наступает эйфория -  всё удобно, просто и быстро выполняется. После нескольких сотен ты не понимаешь, как ты попал в этот ад, когда постоянно ломается что-то другое по непонятным причинам. Узнаваемо?

    Большое количество дополнительных слоёв - в этом различие между UI-тестами и модульными тестами (где слоёв практически нет) и интеграционными тестами (где слои тоже есть, но их значительно меньше).

    Теперь к исходному посту про изменения верстки UI. Когда-то на митапе я услышал вопрос: "А что вы делаете, когда у вас внезапно за ночь полностью поменялся UI интерфейс?". Ответ простой - никогда и ни у кого UI не меняется за ночь внезапно! Изменения в UI, как и любые другие изменения обычно планируются заранее (часто недели и месяцы до изменений). Если вас никто не предупредил о том, что и как изменится в верстке UI - это значит, что падающие тесты - это наименьшая из ваших проблем. Большая проблема, если хотите - смертный грех - в том, что ваша команда дисфункциональна (т.е. неработоспособна) по причине отсутствия коммуникаций. Работайте над починкой это проблемы, прежде чем заниматься тестами.

    Конкретно же - изменения верстки в современной практике легко перехватывается и правится в PageObjects (про правильные PageObjects - см. моё видео  с QAFest 2016).