[Python, Тестирование веб-сервисов] Настройка GitHub Actions для автоматизированного тестирования средствами Python в конвейере CI/CD (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В преддверии старта курса "Python QA Engineer" традиционно публикуем перевод полезного материала.
Также приглашаем присоединиться к открытому вебинару на тему "Автоматизация тестирования API".
В этой статье описываются операции по тестированию клиентской части приложения с помощью TestProject и pytest, а также способы выполнения тестов через GitHub Actions. Если у вас общедоступный репозиторий GitHub, все это будет совершенно бесплатно. Эта возможность хорошо подходит для изучения TestProject и выполнения интеграционного тестирования в ваших проектах. Если вы хотите выполнять эти операции из закрытого репозитория, то GitHub предлагает очень большое количество бесплатных минут, см. https://github.com/features/actions#pricing-details.Карточки репозиториев GitHubСперва я решил изучить возможности, доступные в репозиториях GitHub, поскольку они показались мне довольно простыми для понимания, а к тому же я давно не пользовался Selenium.Я закрепил свои любимые репозитории в верхней части своего сайта waylonwalker.com. Информация для заполнения этих карточек динамически подтягивается на сторону клиента через API-интерфейс GitHub. Это означает, что по мере загрузки страниц JavaScript выполняет скрипты для получения информации от API-интерфейса GitHub, а затем преобразует эти данные в DOM и визуализирует их на странице. Вот как выглядят карточки репозиториев GitHub:
Получение ключейПрежде всего, вам понадобятся TPDEVTOKEN и TPAPIKEY. Эти ключи позволят TestProject получить доступ к вашей учетной записи, чтобы автоматически размещать результаты на вашей панели отчетности.
В своем репозитории GitHub перейдите в раздел settings >Secrets (или добавьте settings/secrets к URL-адресу своего репозитория) и добавьте секретные токены. GitHub получит безопасный доступ к токенам, при этом они не будут доступны широкой публике (включая участников проекта со статусом contributor), не будут отображаться в файлах журналов и т. д.
Настройка среды разработкиЧтобы ускорить работу, я настроил среду разработки в Digital Ocean. Делать это необязательно: все может работать и с вашего локального компьютера или полностью из GitHub Actions. Просто я решил, что, настроив Droplet с Ubuntu в Digital Ocean, я получу условия, близкие к продакшн-среде, а значит, смогу быстрее разработать свои тесты. Это также позволило мне немного ускорить работу всех моих тестов по сравнению с их выполнением через GitHub. При этом процесс был практически таким же, как при использовании GitHub. Таким образом, я смог детально изучить принципы настройки TestProject без необходимости выполнять полную установку при каждом запуске GitHub Actions.
Я не буду здесь подробно описывать настройку машины для разработки. Мои заметки по ее настройке можно прочитать здесь: https://waylonwalker.com/notes/new-machine-tpio.
PytestВсе тесты, выполняющиеся с помощью Pytest, приведены на github.Я решил воспользоваться Pytest. Мне понравилась идея применять фикстуры, автоматически выполнять мои тестовые функции и использовать кое-какие возможности Pytest для формирования отчетов по ходу разработки (при этом платформа TestProject будет работать и без фреймворка для тестирования вроде Pytest).ПРИМЕЧАНИЕ. Следуя стандартным рекомендациям по работе с Pytest, я назвал каталог с тестами именем tests. В целом все работает, но платформа TestProject.io использует этот каталог в качестве имени проекта по умолчанию. Если бы можно было вернуться назад, я либо переименовал бы каталог, задав имя, которое я хочу видеть на TestProject.io, либо задал бы имя проекта в конфигурации.conftest.pyВы можете посмотреть файл conftest.py на GitHub.В файле conftest.py обычно размещаются фикстуры, которые используются несколькими модулями. Pytest автоматически импортирует все модули conftest.py из каталога, в котором вы работаете. Это отличное место для размещения фикстур с драйверами TestProject. Обратите внимание: когда вы используете фикстуру в качестве аргумента в другой функции, фикстура выполнит настройку, передаст все из оператора yield в тестовую функцию, выполнит тестовую функцию, а затем освободит ресурсы.conftest.py хранит фикстуры для всех модулей, находящихся в каталоге.
# tests/conftest.py
import time
import pytest
from src.TestProject.sdk.drivers import web driver
@pytest.fixture
def driver():
"creates a webdriver and loads the homepage"
driver = webdriver.Chrome()
driver.get("https://waylonwalker.com/")
yield driver
driver.quit()
Приведенный выше пример является немного упрощенным. В реальной версии я столкнулся с некоторыми несоответствиями и обнаружил, что процент прохождения некоторых тестов был выше при добавлении оператора time.sleep. В полном проекте я остановился на фикстурах driver и slowdriver. Таким образом, у меня еще есть драйвер, который ждет выполнения JavaScript немного дольше.testrepos.pyПолная версия testrepos.py есть на GitHub.Изначально я настроил три разных теста для карточек репозиториев. Я сформировал список репозиториев, которые должны были отображаться в карточках. Эти тесты довольно легко выполнить с помощью платформы TestProject.io, поскольку она использует Selenium и безголовый браузер для выполнения JavaScript. Область REPOS создана здесь как глобальный список. Ее можно легко переделать в файл конфигурации, если возникнет такая необходимость.Для тех, кто не знает, скажу, что безголовый (headless) браузер работает как обычный браузер, только без графического интерфейса пользователя. JavaScript полностью загружается и парсится, а все взаимодействие с DOM осуществляется программно.Читайте строки документации к каждой функции. В них описано то, что происходит на каждом шаге.
"""
Test that GitHub repo data dynamically loads the client-side.
"""
REPOS = [
"find-kedro",
"kedro-static-viz",
"kedro-action",
"steel-toes",
]
def test_repos_loaded(slow_driver):
"""
Test that each repo-name exists as a title in one of the repo cards.
On waylonwalker.com repo cards have a title with a class of "repo-name"
"""
repos = slow_driver.find_elements_by_class_name("repo-name")
# get innertext from elements
header_text = [
header.text for header in repos
]
for repo in REPOS:
assert repo in header_text
def test_repo_description_loaded(slow_driver):
"""
Test that each repo has a description longer than 10 characters
On waylonwalker.com repo cards have a descriptiion with a class of "repo-description"
"""
repo_elements = slow_driver.find_elements_by_class_name("repo")
for el in repo_elements:
desc = el.find_element_by_class_name("repo-description")
assert len(desc.text) > 10
def test_repo_stars_loaded(slow_driver):
"""
Ensure that stars are correctly parsed from the API and loaded client-side
On waylonwalker.com repo cards have a stars element with a class of "repo-stars" and
is displayed as "n stars"
"""
repo_elements = slow_driver.find_elements_by_class_name("repo")
for el in repo_elements:
stars = el.find_element_by_class_name("repo-stars")
num_stars, label = stars.text.split()
assert int(num_stars) > 0
assert label == 'stars'
ФорумЯ немного запутался с настройкой TestProject.io в Actions. На форуме TestProject я быстро нашел ответ со ссылкой именно на тот пример, который был мне нужен. Пример был написан на Java, но в нем были нужные мне шаги настройки docker-compose.GitHub Actions[test-waylonwalker-com.yml]Итак, репозиторий GitHub настроен, а мои тесты успешно работают в Pytest. Теперь давайте сделаем так, чтобы они автоматически выполнялись в GitHub Actions.Сервис Actions — это решение GitHub для CI/CD. Он позволяет выполнять код на виртуальной машине, управляемой GitHub, которая может получать дополнительную информацию из вашего репозитория, например секретные токены, которые мы настроили в самом начале. Что, как и когда выполняется — все это настраивается в файле yaml.
# .github/workflows/test-waylonwalker-com.yml
name: Test WaylonWalker.com
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '*/10 * * * *'
Как видно в приведенном выше куске кода, я задал выполнение действия при отправке изменений в ветку main (команда push) или при создании pull-запроса, затрагивающего эту ветку. Я также задал достаточно агрессивный график выполнения тестов — каждые 10 минут. Это было необходимо, чтобы убедиться в эффективности тестов и получить больше данных для анализа в отчетах. Позднее я, скорее всего, увеличу этот интервал.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- uses: actions/setup-python@v2
with:
python-version: '3.8'
- run: pip install -r requirements.txt
- name: Run TestProject Agent
env:
TP_API_KEY: ${{ secrets.TP_API_KEY }} # < Let Secrets handle your keys
run: |
envsubst < .github/ci/docker-compose.yml > docker-compose.yml
cat docker-compose.yml
docker-compose -f docker-compose.yml up -d
- name: Wait for Agent to Register
run: bash .github/ci/wait_for_agent.sh
- run: pytest
env:
TP_DEV_TOKEN: ${{ secrets.TP_DEV_TOKEN }} # < Let Secrets handle your tokens
TP_AGENT_URL: http://localhost:8585
В коде задания test видно, что я решил выполнять его на ubuntu-latest. Первые три шага — это достаточно шаблонные действия: переключение на ветку репозитория, установка Python 3.8 и установка зависимостей из файла requirements.txt через pip. Затем ключ TPAPIKEY подставляется в docker-compose.yml с помощью envsubst, далее запускается docker-compose и ожидает готовности агента. Я также предоставил pytest наш токен TPDEVTOKEN и запустил pytest.docker-compose.ymlСледующий файл docker-compose.yml был предоставлен Виталием Буховским (одним из сооснователей и директором по безопасности TestProject) в репозитории testproject-io/java-sdk. Здесь настраивается шаблон с ключом TPAPIKEY в качестве переменной для envsubst, безголовыми браузерами Chrome и Firefox и агентом TestProject.io.
version: "3.1"
services:
testproject-agent:
image: testproject/agent:latest
container_name: testproject-agent
depends_on:
- chrome
- firefox
environment:
TP_API_KEY: "${TP_API_KEY}"
TP_AGENT_TEMP: "true"
TP_SDK_PORT: "8686"
CHROME: "chrome:4444"
CHROME_EXT: "localhost:5555"
FIREFOX: "firefox:4444"
FIREFOX_EXT: "localhost:6666"
ports:
- "8585:8585"
- "8686:8686"
chrome:
image: selenium/standalone-chrome
volumes:
- /dev/shm:/dev/shm
ports:
- "5555:4444"
firefox:
image: selenium/standalone-firefox
volumes:
- /dev/shm:/dev/shm
ports:
- "6666:4444"
Ожидание регистрации агентаwaitforagent.shНа мой взгляд, самая интересная часть приведенного выше потока операций — это то, как мы ожидаем регистрации агента. Скрипт оболочки довольно лаконичный. Он обнаруживает превышение допустимого количества попыток запуска (max_attempts) или наличие запущенного агента путем проверки статуса через REST API (адрес: /api/status). Это позволяет нам избежать потери времени, вызванной заданием слишком большого времени ожидания, или слишком раннего начала процесса, при котором pytest запускается, когда агент еще не работает.
trap 'kill $(jobs -p)' EXIT
attempt_counter=0
max_attempts=100
mkdir -p build/reports/agent
docker-compose -f docker-compose.yml logs -f | tee build/reports/agent/log.txt&
until curl -s http://localhost:8585/api/status | jq '.registered' | grep true; do
if [ ${attempt_counter} -eq ${max_attempts} ]; then
echo "Agent failed to register. Terminating..."
exit 1
fi
attempt_counter=$(($attempt_counter+1))
echo
sleep 1
done
Панель отчетности TestProjectПосле запуска тестов они отображаются на панели TestProject. На ранней стадии разработки тестов возникло несколько сбоев, но после устранения неполадок тесты прогоняются стабильно.
Панель: прохождение одного тестаПанель отчетности позволяет находить отдельные тесты, которые были выполнены, выбирать их и просматривать отчеты по каждому тесту. Она автоматически преобразует шаги, выполненные драйвером, в понятную человеку схему процесса, при этом каждый шаг можно открыть и посмотреть значения, которые были получены драйвером от сайта.
Подробнее о панелях отчетности TestProject можно прочитать по следующим ссылкам:
- HTML-отчеты о тестировании с Selenium и Appium при использовании автоматизации средствами Python
- Общие сведения об отчетах в TestProject
Это пособие создал Уэйлон Уокер (Waylon Walker) на основе своей статьи «Интеграционное тестирование с помощью Python, TestProject.io и GitHub Actions».Удачного тестирования!
- Узнать подробнее о курсе "Python QA Engineer".
- Записаться на открытый вебинар "Автоматизация тестирования API".
===========
Источник:
habr.com
===========
===========
Автор оригинала: Waylon S Walker
===========Похожие новости:
- [JavaScript, Программирование, Angular] RxJS и Angular: искусство отписки от уведомлений (перевод)
- [Программирование, Разработка под Android] Рисование собственных представлений (View) в Android (перевод)
- [Робототехника, Софт] Чем интересна разработка программных роботов RPA?
- [Управление персоналом] Разочарования и проблемы офферов (перевод)
- [Программирование, Разработка под Android, Kotlin] Меняем стандартный диалог сбоя приложения в Android на собственный экран (перевод)
- [Python] Введение в обработку изображений в Python при помощи Pillow (перевод)
- [Информационная безопасность, Тестирование IT-систем, Разработка под Windows] Как работают эксплойты по повышению привилегий в ОС Windows
- [Python, Машинное обучение, Учебный процесс в IT, Искусственный интеллект] Участвуем в соревновании по Data Science. Первый опыт
- [Информационная безопасность, Реверс-инжиниринг] CTF-соревнования 2020 для «белых хакеров». Старт регистрации участников
- [Информационная безопасность, Python, Программирование, Машинное обучение, Искусственный интеллект] Deep Anomaly Detection
Теги для поиска: #_python, #_testirovanie_vebservisov (Тестирование веб-сервисов), #_avtomatizatsija_testirovanija (автоматизация тестирования), #_python, #_github_actions, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_python, #_testirovanie_vebservisov (
Тестирование веб-сервисов
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 06:29
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В преддверии старта курса "Python QA Engineer" традиционно публикуем перевод полезного материала.
Также приглашаем присоединиться к открытому вебинару на тему "Автоматизация тестирования API". В этой статье описываются операции по тестированию клиентской части приложения с помощью TestProject и pytest, а также способы выполнения тестов через GitHub Actions. Если у вас общедоступный репозиторий GitHub, все это будет совершенно бесплатно. Эта возможность хорошо подходит для изучения TestProject и выполнения интеграционного тестирования в ваших проектах. Если вы хотите выполнять эти операции из закрытого репозитория, то GitHub предлагает очень большое количество бесплатных минут, см. https://github.com/features/actions#pricing-details.Карточки репозиториев GitHubСперва я решил изучить возможности, доступные в репозиториях GitHub, поскольку они показались мне довольно простыми для понимания, а к тому же я давно не пользовался Selenium.Я закрепил свои любимые репозитории в верхней части своего сайта waylonwalker.com. Информация для заполнения этих карточек динамически подтягивается на сторону клиента через API-интерфейс GitHub. Это означает, что по мере загрузки страниц JavaScript выполняет скрипты для получения информации от API-интерфейса GitHub, а затем преобразует эти данные в DOM и визуализирует их на странице. Вот как выглядят карточки репозиториев GitHub: Получение ключейПрежде всего, вам понадобятся TPDEVTOKEN и TPAPIKEY. Эти ключи позволят TestProject получить доступ к вашей учетной записи, чтобы автоматически размещать результаты на вашей панели отчетности. В своем репозитории GitHub перейдите в раздел settings >Secrets (или добавьте settings/secrets к URL-адресу своего репозитория) и добавьте секретные токены. GitHub получит безопасный доступ к токенам, при этом они не будут доступны широкой публике (включая участников проекта со статусом contributor), не будут отображаться в файлах журналов и т. д. Настройка среды разработкиЧтобы ускорить работу, я настроил среду разработки в Digital Ocean. Делать это необязательно: все может работать и с вашего локального компьютера или полностью из GitHub Actions. Просто я решил, что, настроив Droplet с Ubuntu в Digital Ocean, я получу условия, близкие к продакшн-среде, а значит, смогу быстрее разработать свои тесты. Это также позволило мне немного ускорить работу всех моих тестов по сравнению с их выполнением через GitHub. При этом процесс был практически таким же, как при использовании GitHub. Таким образом, я смог детально изучить принципы настройки TestProject без необходимости выполнять полную установку при каждом запуске GitHub Actions. Я не буду здесь подробно описывать настройку машины для разработки. Мои заметки по ее настройке можно прочитать здесь: https://waylonwalker.com/notes/new-machine-tpio.
PytestВсе тесты, выполняющиеся с помощью Pytest, приведены на github.Я решил воспользоваться Pytest. Мне понравилась идея применять фикстуры, автоматически выполнять мои тестовые функции и использовать кое-какие возможности Pytest для формирования отчетов по ходу разработки (при этом платформа TestProject будет работать и без фреймворка для тестирования вроде Pytest).ПРИМЕЧАНИЕ. Следуя стандартным рекомендациям по работе с Pytest, я назвал каталог с тестами именем tests. В целом все работает, но платформа TestProject.io использует этот каталог в качестве имени проекта по умолчанию. Если бы можно было вернуться назад, я либо переименовал бы каталог, задав имя, которое я хочу видеть на TestProject.io, либо задал бы имя проекта в конфигурации.conftest.pyВы можете посмотреть файл conftest.py на GitHub.В файле conftest.py обычно размещаются фикстуры, которые используются несколькими модулями. Pytest автоматически импортирует все модули conftest.py из каталога, в котором вы работаете. Это отличное место для размещения фикстур с драйверами TestProject. Обратите внимание: когда вы используете фикстуру в качестве аргумента в другой функции, фикстура выполнит настройку, передаст все из оператора yield в тестовую функцию, выполнит тестовую функцию, а затем освободит ресурсы.conftest.py хранит фикстуры для всех модулей, находящихся в каталоге. # tests/conftest.py
import time import pytest from src.TestProject.sdk.drivers import web driver @pytest.fixture def driver(): "creates a webdriver and loads the homepage" driver = webdriver.Chrome() driver.get("https://waylonwalker.com/") yield driver driver.quit() """
Test that GitHub repo data dynamically loads the client-side. """ REPOS = [ "find-kedro", "kedro-static-viz", "kedro-action", "steel-toes", ] def test_repos_loaded(slow_driver): """ Test that each repo-name exists as a title in one of the repo cards. On waylonwalker.com repo cards have a title with a class of "repo-name" """ repos = slow_driver.find_elements_by_class_name("repo-name") # get innertext from elements header_text = [ header.text for header in repos ] for repo in REPOS: assert repo in header_text def test_repo_description_loaded(slow_driver): """ Test that each repo has a description longer than 10 characters On waylonwalker.com repo cards have a descriptiion with a class of "repo-description" """ repo_elements = slow_driver.find_elements_by_class_name("repo") for el in repo_elements: desc = el.find_element_by_class_name("repo-description") assert len(desc.text) > 10 def test_repo_stars_loaded(slow_driver): """ Ensure that stars are correctly parsed from the API and loaded client-side On waylonwalker.com repo cards have a stars element with a class of "repo-stars" and is displayed as "n stars" """ repo_elements = slow_driver.find_elements_by_class_name("repo") for el in repo_elements: stars = el.find_element_by_class_name("repo-stars") num_stars, label = stars.text.split() assert int(num_stars) > 0 assert label == 'stars' # .github/workflows/test-waylonwalker-com.yml
name: Test WaylonWalker.com # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: push: branches: [ main ] pull_request: branches: [ main ] schedule: - cron: '*/10 * * * *' jobs:
test: runs-on: ubuntu-latest steps: - uses: actions/checkout@main - uses: actions/setup-python@v2 with: python-version: '3.8' - run: pip install -r requirements.txt - name: Run TestProject Agent env: TP_API_KEY: ${{ secrets.TP_API_KEY }} # < Let Secrets handle your keys run: | envsubst < .github/ci/docker-compose.yml > docker-compose.yml cat docker-compose.yml docker-compose -f docker-compose.yml up -d - name: Wait for Agent to Register run: bash .github/ci/wait_for_agent.sh - run: pytest env: TP_DEV_TOKEN: ${{ secrets.TP_DEV_TOKEN }} # < Let Secrets handle your tokens TP_AGENT_URL: http://localhost:8585 version: "3.1"
services: testproject-agent: image: testproject/agent:latest container_name: testproject-agent depends_on: - chrome - firefox environment: TP_API_KEY: "${TP_API_KEY}" TP_AGENT_TEMP: "true" TP_SDK_PORT: "8686" CHROME: "chrome:4444" CHROME_EXT: "localhost:5555" FIREFOX: "firefox:4444" FIREFOX_EXT: "localhost:6666" ports: - "8585:8585" - "8686:8686" chrome: image: selenium/standalone-chrome volumes: - /dev/shm:/dev/shm ports: - "5555:4444" firefox: image: selenium/standalone-firefox volumes: - /dev/shm:/dev/shm ports: - "6666:4444" trap 'kill $(jobs -p)' EXIT
attempt_counter=0 max_attempts=100 mkdir -p build/reports/agent docker-compose -f docker-compose.yml logs -f | tee build/reports/agent/log.txt& until curl -s http://localhost:8585/api/status | jq '.registered' | grep true; do if [ ${attempt_counter} -eq ${max_attempts} ]; then echo "Agent failed to register. Terminating..." exit 1 fi attempt_counter=$(($attempt_counter+1)) echo sleep 1 done Панель: прохождение одного тестаПанель отчетности позволяет находить отдельные тесты, которые были выполнены, выбирать их и просматривать отчеты по каждому тесту. Она автоматически преобразует шаги, выполненные драйвером, в понятную человеку схему процесса, при этом каждый шаг можно открыть и посмотреть значения, которые были получены драйвером от сайта. Подробнее о панелях отчетности TestProject можно прочитать по следующим ссылкам:
- Узнать подробнее о курсе "Python QA Engineer".
- Записаться на открытый вебинар "Автоматизация тестирования API". =========== Источник: habr.com =========== =========== Автор оригинала: Waylon S Walker ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_python, #_testirovanie_vebservisov ( Тестирование веб-сервисов ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 06:29
Часовой пояс: UTC + 5