«Учитывая наше восхищение pytest, мы выбрали плагин Playwright-pytest для исследования. Хотя нас впечатлила интеграция с pytest, мы заметили, что в официальной документации и документации комьюнити представлены только синхронные примеры с использованием pytest. Этот пост, надеемся, восполнит пробел. Мы решили, что работа над адаптацией pytest к асинхронности Playwright также поможет лучше понять внутреннее устройство Playwright. В этом посте мы покажем вам, как создать простой UI-тест Playwright с помощью pytest.
Примечание: Этот пост предполагает, что вы уже знакомы с Playwright и использовали pytest для написания синхронных UI-тестов.
Создание асинхронной фикстуры pytest
Предварительно загруженные фикстуры pytest для Playwright делают написание тестов простой задачей, но, к сожалению, такие фикстуры используют только синхронные API. Сложность состоит в том, чтобы создать фикстуры для работы с корутинами. Мы используем pytest_asyncio для создания асинхронного теста API. Сейчас будем использовать pytest_asyncio для создания асинхронной фикстуры, чтобы:
- Запустить Playwright
- Открыть браузер
- Создать новую страницу
# Contents of conftest.py file import pytest_asyncio from playwright.async_api import async_playwright @pytest_asyncio.fixture async def async_page(pytestconfig): "Async fixture to return a Playwright Page" browser = pytestconfig.getoption("--browser") async with async_playwright() as playwright: browser_obj = getattr(playwright,browser[0]) if browser_obj: browser = await browser_obj.launch() page = await browser.new_page() yield page
Асинхронная фикстура использует менеджер контекста для запуска службы Playwright и ее остановки при выходе, применяет CLI-параметр --browser
для получения входных данных браузера и возвращает новую страницу.
Примечание: Код предназначен только для демонстрационных целей. Мы рекомендуем следовать лучшим стандартам кода в реальных приложениях.
Создание асинхронного UI-теста
Теперь, когда у нас есть асинхронная фикстура, создание теста — простая задача. Мы можем создавать корутинные тестовые функции с помощью pytest_asyncio
. Тесты, которые мы создадим, будут валидировать следующие сценарии:
- Лендинг пользователя
- Форма на странице
Валидация лендинга
Сценарий первой тестовой функции — валидация лендинга пользователя на Selenium Tutorial Page. Для создания тестовой функции можем использовать созданную нами фикстуру async_page
. Должен быть использован маркер @pytest.mark.asyncio
, чтобы pytest собрал корутину в качестве теста.
@pytest.mark.asyncio async def test_has_title(async_page): "Validate Tutorial Main page title" await async_page.goto("https://qxf2.com/selenium-tutorial-main") title = await async_page.title() assert title == "Qxf2 Services: Selenium training main"
Валидация формы на странице
Сценарий для второй тестовой функции заключается в валидации формы на той же странице.
@pytest.mark.asyncio async def test_contact_form(async_page): "Validate contact form" await async_page.goto("https://qxf2.com/selenium-tutorial-main") await async_page.get_by_role("textbox", name="name").fill("Jonathan Wick") await async_page.locator("xpath=//input[@name='email']").fill("john@qxf2.com") await async_page.locator("xpath=//input[@name='phone']").fill("0000000000") await async_page.locator("xpath=//button[@type='submit']").click() redirect_title = await async_page.title() assert redirect_title == "Qxf2 Services: Selenium training redirect"
Теперь объединяем
Собираем тестовые функции в модуле test_async_tutorial_page.py
:
@pytest.mark.asyncio async def test_has_title(async_page): "Validate Tutorial Main page title" await async_page.goto("https://qxf2.com/selenium-tutorial-main") title = await async_page.title() assert title == "Qxf2 Services: Selenium training main" @pytest.mark.asyncio async def test_contact_form(async_page): "Validate contact form" await async_page.goto("https://qxf2.com/selenium-tutorial-main") await async_page.get_by_role("textbox", name="name").fill("Jonathan Wick") await async_page.locator("xpath=//input[@name='email']").fill("john@qxf2.com") await async_page.locator("xpath=//input[@name='phone']").fill("0000000000") await async_page.locator("xpath=//button[@type='submit']").click() redirect_title = await async_page.title() assert redirect_title == "Qxf2 Services: Selenium training redirect"
Примечание: В реальном мире этот пример будет полезен, если вы например автоматизируете квиз с десятками вопросов.
Запуск теста
Чтобы запустить тест, выполните команду:
pytest --browser chromium -s -v
Вот и все, имеем простой асинхронный тест интерфейса в Playwright, использующий pytest. В нем представлен только базовый пример использования pytest для создания асинхронного UI-теста Playwright, но если хотите создать/модифицировать собственный форк фреймворка Playwright-pytest, поддерживающий асинхронность, воспользуйтесь файлом conftest.py для создания собственных асинхронных фикстур.»