Всем привет! Меня зовут Илья. Я начинающий автотестировщик. В этой статье кратко расскажу о том, как при стечении нескольких положительных обстоятельств нам удалось быстро поднять систему автотестов для нашего web-приложения.
Тестируемое web-приложение
Опыт может оказаться полезен тестировщикам, которые работают в компаниях, где только начинает развиваться автотестирование и нет штатных специалистов по обслуживанию/разворачиванию серверов.
Стек web-приложения и backend части
Backend: Python + MongoDB + Elasticsearch
Frontend: React application
Чтобы развернуть приложение на сервере используется Docker и Yarn.
Каких целей мы хотели достичь создавая описанную ниже инфраструктуру:
Селекторы (Кнопочки, текст, картинки и прочие элементы интерфейса web-приложения.)
Действия с селекторами (Это простейшие python функции, которые позволяют оперировать селекторами. Пример: найди кнопку и сделай клик по ней. Найди поле и вставь туда значение.)
Пример селекторов и действий с ними.
Функции (Речь опять идет о python функциях, только более сложных. С точки зрения кода функции оперируют действиями с селекторами, определяют, должно ли в данный момент выполниться то или иное действие. Пример: в нашем web-приложении есть профиль пользователя. Его можно редактировать. Все операции по редактированию этого профиля собираются в одной функции. Другая функция: регистрация пользователя. Пройти регистрацию можно несколькими способами и все они описаны внутри одной функции.)
Порядок выполнения функций (Каждый автотест - это некая последовательность действий в web-приложении. Порядок функций определит как именно будут развиваться события в нашем автотесте. Пример: сначал функция регистрации должна зарегистрировать пользователя, потом вторая функция должна создать "программу" (специфическая часть нашего web-приложения, не будем вдаваться в подробности), затем третья функция пригласит другого пользователя в эту программу и тд.)
Таким образом в QASE можно хранить сам автотест и порядок выполняемых в нем функций. У части функций в параметрах прописан номер тест кейса, содержащий входные данные для этой функции. Следующая картинка будет как раз примером входных данных для action.program_create()
Входные данные для функций (Почти все написанные функции ждут, что им на вход придут данные, которыми функция сможет оперировать. Например: функция создания программы ожидает от нас сведения о наименовании программы, ее описание, стоимость и еще множество других сведений, которые позволят функции в рамках автотеста создать именно ту программу, какую хочет тестировщик.)
Пример входных данных для функции. Этот кусочек кода хранится в QASE под номером 39. Именно этот номер мы указываем в параметрах функций, когда описывваем в QASE порядок выполнения функций в тест кейсе.
Зачем часть сведений хранить в QASE?
Таким образом мы делим работу над автотестами на две части. С кодом работают ребята, которые знают python и понимают селекторы.
В QASE работают коллеги, которые могут из функций и входных данных как из лего собирать любое количество автотестов, тем самым проверяя продукт вдоль и поперек под самыми разными точками зрения.
Так как тесты состоят из элементов, хранящихся в разных системах, перед запуском тестов надо организовать их сбор в единое целое:
Файл, собирающий все элементы в единое целое. При вызове этого файла с командой pytest начнется прогон автотестов.
Так как перед стартом прогона мы инициируем начало тест рана в QASE и по мере прохождения тестов передаем в QASE информацию о результатах тестирования, то получить отчет о тестировании становится довольно просто.
У QASE есть интеграция со Slack. И по триггеру окончания тест рана отчет автоматически отправится в нужный чатик Slack, где с ним может ознакомиться любое заинтересованное лицо.
Пример небольшого отчета в Slack по прохождению 6 автотестов. Один упал. При клике на назввание тест рана в браузере откроется полный отчет о тестировании с перечислением всех ошибок, успешно пройденных тест кейсов и историей предыдущих прогонов.
Опыт может оказаться полезен тестировщикам, которые работают в компаниях, где только начинает развиваться автотестирование и нет штатных специалистов по обслуживанию/разворачиванию серверов.
Стек web-приложения и backend части
Backend: Python + MongoDB + Elasticsearch
Frontend: React application
Чтобы развернуть приложение на сервере используется Docker и Yarn.
Каких целей мы хотели достичь создавая описанную ниже инфраструктуру:
- Критический функционал проверяется при каждом push/merge в GitHub в течение 15 минут, что дает разработчикам возможность быстро получить результаты тестов и поправить баги, не теряя констекста.
- Полное регрессионное тестирование проходит каждую ночь и на утро дает четкое представление о текущем состоянии продукта.
- Сервер на актуальной Ubuntu. Чтобы поднять backend и frontend web-приложения использовали Docker и Yarn, чтобы принимать webhooks подняли Flask, а сами автотесты, написанные на python, пользуются услугами Selenium, Selenoid, Pytest.
- После push в GitHub на сервере запускаются автотесты, а после завершения тестов отчет о тестировании приходит в чатик Slack.
- Вся инфраструктура обходится в $60/мес (сервер платный, все остальное бесплатно)
- Свежий код backend или frontend пушится в GitHub;
- GitHub по событию push отправляет webhook на сервер, где крутятся тесты;
- Когда сервер принимает webhook запускается bash скрипт;
- Bash скрипт стягивает обновления из репозитория (от которого пришла команда) и запускает Yarn, чтобы поднялся frontend;
- Когда поднялся frontend bash скрипт дает команду на запуск python функции, которая с помощью бесплатного API отправляет в QASE команду на старт тест рана. Вторым запросом из QASE получаем всю информацию о самих автотестах (об этом ниже). После этого Pytest запускает автотесты;
- Каждый запускаемый автотест влечет за собой следующие события:
- Очищается база данных web-приложения;
- Selenoid запускает отдельный контейнер с браузером выбранной версии, нужным разрешением экрана, а в процессе выполнения теста ведет видео запись того, как проходит тест;
- Параллельно с тем, как идет тест засекается время выполнения теста;
- По окончании теста информация об успешном завершении теста (или ошибке) вместе с продолжительностью теста отправляется по API в QASE, чтобы эта информация была сохранена в рамках действующего тест рана;
- По окончании теста контейнер с браузером убивается и стартует новый тест.
- По окончании последнего теста по API в QASE отправляем информацию о заверешнии тест рана;
- Как только QASE получит команду на завершение тест рана он сформирует отчет о тестировании с красивыми графиками, всеми найденными ошибками и отправит этот отчет в Slack чатик тестировщиков, где с отчетом могут ознакомиться тестировщики, разработчики и начальство.
Как реализованы автотесты?
Элементы, из которых состоят автотесты, можно разделить на 5 уровней:Селекторы (Кнопочки, текст, картинки и прочие элементы интерфейса web-приложения.)
Действия с селекторами (Это простейшие python функции, которые позволяют оперировать селекторами. Пример: найди кнопку и сделай клик по ней. Найди поле и вставь туда значение.)
Функции (Речь опять идет о python функциях, только более сложных. С точки зрения кода функции оперируют действиями с селекторами, определяют, должно ли в данный момент выполниться то или иное действие. Пример: в нашем web-приложении есть профиль пользователя. Его можно редактировать. Все операции по редактированию этого профиля собираются в одной функции. Другая функция: регистрация пользователя. Пройти регистрацию можно несколькими способами и все они описаны внутри одной функции.)
Порядок выполнения функций (Каждый автотест - это некая последовательность действий в web-приложении. Порядок функций определит как именно будут развиваться события в нашем автотесте. Пример: сначал функция регистрации должна зарегистрировать пользователя, потом вторая функция должна создать "программу" (специфическая часть нашего web-приложения, не будем вдаваться в подробности), затем третья функция пригласит другого пользователя в эту программу и тд.)
Входные данные для функций (Почти все написанные функции ждут, что им на вход придут данные, которыми функция сможет оперировать. Например: функция создания программы ожидает от нас сведения о наименовании программы, ее описание, стоимость и еще множество других сведений, которые позволят функции в рамках автотеста создать именно ту программу, какую хочет тестировщик.)
Зачем часть сведений хранить в QASE?
Таким образом мы делим работу над автотестами на две части. С кодом работают ребята, которые знают python и понимают селекторы.
В QASE работают коллеги, которые могут из функций и входных данных как из лего собирать любое количество автотестов, тем самым проверяя продукт вдоль и поперек под самыми разными точками зрения.
Так как тесты состоят из элементов, хранящихся в разных системах, перед запуском тестов надо организовать их сбор в единое целое:
- Первым делом забрем из QASE все данные о прогоняемых тест кейсах. Делаем это функцией qase_get_data(), которая по API получает полный перечень тест кейсов, а для каждого конкретного теста очередность выполнения функций внутри этого теста и входные данные для функций.
- С помощью параметризации pytest собирает все автотесты в одну очередь.
- С помощью exec() (используйте эту функцию только в случае, когда уверены в безопасности получаемых данных) передаем pytest информацию о функциях, которые будут выполняться в каждом тесте.
- Далее pytest будет согласно очереди запускать автотесты.
Так как перед стартом прогона мы инициируем начало тест рана в QASE и по мере прохождения тестов передаем в QASE информацию о результатах тестирования, то получить отчет о тестировании становится довольно просто.
У QASE есть интеграция со Slack. И по триггеру окончания тест рана отчет автоматически отправится в нужный чатик Slack, где с ним может ознакомиться любое заинтересованное лицо.
Вместо заключения хочется сказать о нюансах
- выбранный нами сервер при однопоточном запуске автотестов нагружается на 60% и запускать тесты параллельно на нем возможности нет, хотя в архитектуре эта возможность заложена. Другими словами, когда потребуется сократить время на прохождение автотестов, бюджет надо будет поднимать до условных $300, чтобы взять сервер на 32 гигабайта оперативной памяти.
- в некоторых автотестах требуется загружать в web-приложение файлы (аватарки, документы и прочее). Такие файлы мы тоже вынести в QASE и скачиваем оттуда в тот момент, когда приходит время выполнить тест кейс, в котором эти файлы используются.
- для того, чтобы автотесты можно было запускать без привязки к GitHub сделали отдельный роут на Flask, который позволяет в параметрах передать номера тест кейсов, которые сейчас надо прогнать. Если в параметрах ничего не указано, то будет запущен тест ран со всеми имеющимися автотестами.
Как генерировать UI автотесты из документации? Используем Python, Pytest, Selenium и QASE.io
Всем привет! Меня зовут Илья. Я люблю писать автотесты на python. В этой статье кратко расскажу о том, как при стечении нескольких положительных обстоятельств нам удалось быстро поднять систему...
habr.com