Pull to refresh
0

Автоматизация тестирования вебсайта: Pytest, Allure, Selenium + несколько секретных ингредиентов

Reading time 5 min
Views 19K
Уже больше года у Acronis новый логотип, о том, как он создавался можно прочитать тут. В рамках ребрендинга обновился и сайт www.acronis.com. Для построения сайта мы выбрали CMS Drupal. Сайт получился классный снаружи и непростой внутри: 28 локалей (!), отзывчивый веб-дизайн, карусели, визарды, всплывающие окна… в итоге пришлось задействовать множество различных модулей друпала, некоторые из них кастомизировать и писать собственные. При работе такой динамичной, сложной системы неизбежны ошибки. Их предотвращением и выявлением занимается команда контроля и обеспечения качества вебсайта. В этой статье мы хотим поделиться своим успешным рецептом автоматизации тестирования нашего сайта.



Почему и зачем?


К сожалению, на начальном этапе жизни нашего сайта на страже качества были,  в основном, только возможности ручного тестирования. Учитывая короткие релиз-циклы, регрессионные тесты приходилось прогонять часто. Большое количество локалей усугубляло ситуацию (проверки умножались на количество локалей). Затраты на ручное тестирование были большими, а выгода автоматизации тестирования сайта очевидной – надо было действовать.

Чего хотим?


Итак, начинаем составлять требования к системе автоматического тестирования. Мы заметили, что на обработку достаточно простых дефектов тратится драгоценное время, захотелось минимизировать количество заводимых в баг-трекер дефектов, но не теряя такие ошибки из поля зрения. Поэтому работу с такими дефектами было решено возложить на систему отчетов автотестов. Требовалось, чтобы репортинг был очень удобным, понятным, информативным и приятным. Таким, чтобы любой член нашей дружной web-команды мог посмотреть отчет, быстро понять, в чем дело, и пофиксить дефект. Соответственно все смотрят: разработчики фиксят сайт, тестировщики фиксят тесты. В итоге имеем «зеленый сигнал светофора» и GO в продакшн.

Исторически сложилось ещё одно требование – язык разработки Python. Опуская подробности остальных пожеланий, мы получили перечень требований для будущей системы автоматического тестирования:

  • Удобный, понятный, информативный репортинг;.
  • Параллельный запуск тестов;
  • Параметризация тестов;
  • Наследования тестовых данных по локалям;
  • Тестирование в среде, наиболее приближенной к пользователю;
  • Минимизация ложных срабатываний;
  • Удобная поддержка и доставка окружения для тестирования;
  • Минимум собственной разработки и кастомизации;
  • Open source;
  • Python.

Муки выбора


Первым делом мы обратили внимание на Robot Framework. Это популярное решение, которое уже упоминалось в публикациях Acronis. Установили, начали пробовать. Плюсов, конечно, много, но сейчас не о них. Основное противопоказание для нас – это работа RF с параметризованными тестами и штатный репортинг результатов для них. Следует заметить, что абсолютное большинство задуманных нами тестов – это именно параметризованные тесты. В отчете RF, если один из случаев в параметризованном тесте провален, то весь тест помечается как проваленный. Также репортинг RF из коробки был неудобен для большинства наших ребят – много времени уходило на разбор результатов пробных автотестов. Своеобразное «простое» написание тестов при помощи ключевых слов в случает тестов посложнее оказалось непростой задачей. В то же время, благодаря в том числе и Хабру, мы обратили внимание на Allure от Яндекс.

Посмотрели, всем понравилось, у всех возникло желание работать с этой системой, что, надо заметить, очень важно. Мы изучили инструмент, убедились, что проект активно развивается, имеет много готовых адаптеров для различных популярных тестовых фреймворков, в том числе и для python. К сожалению (а может, и к счастью) оказалось, что для python существует адаптер только для фреймворка pytest. Посмотрели, почитали, попробовали – оказалось, крутая штука. Pytest много всего умеет, прост в использовании, расширяемый функционал за счёт готовых и собственных плагинов, большое интернет-сообщество, ну а параметризация тестов на нем такая, как нам нужна! Запустили, написали пару пробных тестов, все отлично. Теперь дело за параллельным выполнением тестов, тут выбор решений невелик – только pytest-xdist. Установили, запустили и…

Ложка дегтя


Оказалось, что pytest-xdist конфликтует с Allure Pytest Adaptor. Начали разбираться, проблема известная, уже длительное время обсуждается и не решена. Также готового решения для наследовании тестовых данных по локалям найти не удалось,

Секретные ингредиенты


Чтобы обойти эти проблемы, мы решаем написать тул (обертку) на python. Эта обертка будет подготавливать тестовые данные с учетом наследования, передавать их тестам, передавать тестам данные тестовой среды (браузер, например) а также запускать тесты в заданное количество потоков. После выполнения тестов – объединять полученные в разных потоках отчеты в один и публиковать конечные данные на вебсайт.

Параллелинг решили реализовать достаточно просто, как параллельный вызов каждого единичного теста через командную строку.  При таком подходе пришлось реализовывать передачу тестовых данных в тест самостоятельно. Благодаря фикстурам в pytest это дело нескольких строк. Важно! Также необходимо закомментировать пару строк в (allure-python/allure/common.py), отвечающих за удаление «старых» файлов в директории отчетов allure адаптера.

Тестовые данные для параметризованных тестов решено было хранить в tsv-файлах, статичные тестовые данные – в yaml. Принадлежность тестовых данных к тесту и локали решили определять при помощи названий и иерархии директорий, в которых эти данные находятся. Наследование ведется от основной базовой локали «en-us», путём удаления, добавления уникальных данных. Также в тестовых данных возможно использовать ключевое слово ‘skip’ и  ‘comment’ – для отмены запуска конкретного тестового случая с указанием причины. Такое наследование, например, если необходимо использовать одни и те же данные для всех локализаций сайта, то наследование происходит автоматически без каких-либо дополнительных параметров. Кстати, для данных конфигураций теста (окружение, время ожидания и т.д.) также реализовали наследование, но уже не на основе локализации, а на основе наследования глобального конфигурационного файла, конфигами тестов.



Ещё один нюанс


Получая первые отчеты, начали думать, как удобнее отображать результаты тестов в разрезе локалей. Мы посчитали, что наиболее удобно для нас разделять результаты по принципу – каждой локали свой экземпляр allure-отчета. А для агрегации общей информации по локалям мы быстренько написали простенькую, но симпатичную обёртку.





Последнее, что омрачало нашу радость, это случаи зависания отдельных запусков в тестовой среде. Забыл упомянуть, что в качестве среды для тестирования мы решили использовать классический Selenium (как окружение, наиболее приближенное к реальному). При большом количестве проверок в selenium сбоев не избежать. А также всеми «любимые» ложные срабатывания, они очень затрудняют непрерывную интеграцию и «зеленый сигнал светофора» для продакшн.

Подумали и нашли выход. Зависания – побороли доработкой нашей обертки. Добавили возможность указать максимальное время выполнения отдельного теста и, если он не выполняется за указанное время, мы его грубо перезапускаем. А ложные срабатывания убрали при помощи дополнения rerun-xfails для pytest. Этот плагин автоматически перезапускает все проваленные тесты, количество попыток опять же задаем в конфигурационном yaml-файле для каждого теста или общий.

Эпилог


И, наконец, вот оно – счастье начинающего автоматизатора: стабильная удобная рабочая система. Она проста в обслуживании, позволяет провести тестирование максимально быстро и без ложных срабатываний, предоставляет очень удобную отчетность о результатах тестирования.

P.S.


Друзья, по вашим фидбекам здесь на Хабре мы бы хотели понять, насколько интересен наш опыт. Есть идея опубликовать получившееся готовое решение в виде docker-контейнера.
Tags:
Hubs:
+16
Comments 10
Comments Comments 10

Articles

Information

Website
www.acronis.com
Registered
Founded
Employees
1,001–5,000 employees
Location
Сингапур