Перейти к основному содержимому

Справочник плагина Pytest

Введение​

Playwright предоставляет плагин Pytest для написания end-to-end тестов. Чтобы начать работу с ним, обратитесь к руководству по началу работы.

Использование​

Для запуска ваших тестов используйте CLI Pytest.

pytest --browser webkit --headed

Если вы хотите добавить аргументы CLI автоматически, не указывая их, вы можете использовать файл pytest.ini:

# содержимое pytest.ini
[pytest]
# Запуск firefox с UI
addopts = --headed --browser firefox

Аргументы CLI​

Обратите внимание, что аргументы CLI применяются только к стандартным фикстурам browser, context и page. Если вы создаете браузер, контекст или страницу с помощью вызова API, например browser.new_context(), аргументы CLI не применяются.

  • --headed: Запуск тестов в режиме с интерфейсом (по умолчанию: без интерфейса).
  • --browser: Запуск тестов в другом браузере chromium, firefox или webkit. Может быть указан несколько раз (по умолчанию: chromium).
  • --browser-channel Канал браузера, который будет использоваться.
  • --slowmo Замедляет операции Playwright на указанное количество миллисекунд. Полезно, чтобы увидеть, что происходит (по умолчанию: 0).
  • --device Устройство, которое будет эмулироваться.
  • --output Директория для артефактов, созданных тестами (по умолчанию: test-results).
  • --tracing Записывать ли трассировку для каждого теста. on, off или retain-on-failure (по умолчанию: off).
  • --video Записывать ли видео для каждого теста. on, off или retain-on-failure (по умолчанию: off).
  • --screenshot Автоматически ли делать скриншот после каждого теста. on, off или only-on-failure (по умолчанию: off).
  • --full-page-screenshot Делать ли скриншот всей страницы при ошибке. По умолчанию захватывается только видимая область. Требует включения --screenshot (по умолчанию: off).

Фикстуры​

Этот плагин настраивает специфичные для Playwright фикстуры для pytest. Чтобы использовать эти фикстуры, используйте имя фикстуры в качестве аргумента для тестовой функции.

def test_my_app_is_working(fixture_name):
pass
# Тест с использованием fixture_name
# ...

Область действия функции: Эти фикстуры создаются при запросе в тестовой функции и уничтожаются, когда тест завершается.

Область действия сессии: Эти фикстуры создаются при запросе в тестовой функции и уничтожаются, когда все тесты завершаются.

  • playwright: Экземпляр Playwright.
  • browser_type: Экземпляр BrowserType текущего браузера.
  • browser: Экземпляр Browser, запущенный Playwright.
  • browser_name: Имя браузера в виде строки.
  • browser_channel: Канал браузера в виде строки.
  • is_chromium, is_webkit, is_firefox: Булевы значения для соответствующих типов браузеров.

Настройка опций фикстур: для фикстур browser и context используйте следующие фикстуры, чтобы задавать пользовательские опции запуска.

  • browser_type_launch_args: переопределяет аргументы запуска для browser_type.launch(). Должна возвращать Dict.
  • browser_context_args: переопределяет опции для browser.new_context(). Должна возвращать Dict.
  • connect_options: подключается к существующему браузеру через WebSocket endpoint. Должна возвращать Dict с опциями browser_type.connect().

Также возможно переопределить параметры контекста (browser.new_context()) для одного теста, используя маркер browser_context_args:

import pytest

@pytest.mark.browser_context_args(timezone_id="Europe/Berlin", locale="en-GB")
def test_browser_context_args(page):
assert page.evaluate("window.navigator.userAgent") == "Europe/Berlin"
assert page.evaluate("window.navigator.languages") == ["de-DE"]

Параллелизм: Запуск нескольких тестов одновременно​

Если ваши тесты выполняются на машине с большим количеством процессоров, вы можете ускорить общее время выполнения вашего набора тестов, используя pytest-xdist для одновременного запуска нескольких тестов:

# установка зависимости
pip install pytest-xdist
# использование флага --numprocesses
pytest --numprocesses auto

В зависимости от оборудования и характера ваших тестов, вы можете установить numprocesses от 2 до количества процессоров на машине. Если установить слишком высокое значение, вы можете заметить непредвиденное поведение.

Смотрите Запуск тестов для общей информации о параметрах pytest.

Примеры​

Настройка типов для автозаполнения​

test_my_application.py
from playwright.sync_api import Page

def test_visit_admin_dashboard(page: Page):
page.goto("/admin")
# ...

Если вы используете VSCode с Pylance, эти типы могут быть выведены автоматически, включив настройку python.testing.pytestEnabled, чтобы вам не нужно было указывать аннотацию типа.

Использование нескольких контекстов​

Чтобы симулировать нескольких пользователей, вы можете создать несколько экземпляров BrowserContext.

test_my_application.py
from playwright.sync_api import Page, BrowserContext
from pytest_playwright.pytest_playwright import CreateContextCallback

def test_foo(page: Page, new_context: CreateContextCallback) -> None:
page.goto("https://example.com")
context = new_context()
page2 = context.new_page()
# page и page2 находятся в разных контекстах

Пропуск теста для определенного браузера​

test_my_application.py
import pytest

@pytest.mark.skip_browser("firefox")
def test_visit_example(page):
page.goto("https://example.com")
# ...

Запуск на конкретном браузере​

conftest.py
import pytest

@pytest.mark.only_browser("chromium")
def test_visit_example(page):
page.goto("https://example.com")
# ...

Запуск с использованием пользовательского канала браузера, например, Google Chrome или Microsoft Edge​

pytest --browser-channel chrome
test_my_application.py
def test_example(page):
page.goto("https://example.com")

Настройка базового URL​

Запустите Pytest с аргументом base-url. Для этого используется плагин pytest-base-url, который позволяет установить базовый URL из конфигурации, аргумента CLI или как фикстуру.

pytest --base-url http://localhost:8080
test_my_application.py
def test_visit_example(page):
page.goto("/admin")
# -> Результат будет http://localhost:8080/admin

Игнорирование ошибок HTTPS​

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"ignore_https_errors": True
}

Использование пользовательского размера окна просмотра​

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"viewport": {
"width": 1920,
"height": 1080,
}
}

Эмуляция устройства / Переопределение параметров BrowserContext​

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, playwright):
iphone_11 = playwright.devices['iPhone 11 Pro']
return {
**browser_context_args,
**iphone_11,
}

Или через CLI --device="iPhone 11 Pro"

Подключение к удалённым браузерам​

conftest.py
import pytest

@pytest.fixture(scope="session")
def connect_options():
return {
"wsEndpoint": "ws://localhost:8080/ws"
}

Использование с unittest.TestCase​

Смотрите следующий пример для использования с unittest.TestCase. Это имеет ограничение, что может быть указан только один браузер, и не создается матрица из нескольких браузеров при указании нескольких.

import pytest
import unittest

from playwright.sync_api import Page


class MyTest(unittest.TestCase):
@pytest.fixture(autouse=True)
def setup(self, page: Page):
self.page = page

def test_foobar(self):
self.page.goto("https://microsoft.com")
self.page.locator("#foobar").click()
assert self.page.evaluate("1 + 1") == 2

Отладка​

Использование с pdb​

Используйте оператор breakpoint() в вашем тестовом коде, чтобы приостановить выполнение и получить REPL pdb.

def test_bing_is_working(page):
page.goto("https://bing.com")
breakpoint()
# ...

Развертывание в CI​

Смотрите руководства для провайдеров CI, чтобы развернуть ваши тесты в CI/CD.

Асинхронные фикстуры​

Чтобы использовать асинхронные фикстуры, установите pytest-playwright-asyncio.

Убедитесь, что вы используете pytest-asyncio>=0.26.0, и задайте asyncio_default_test_loop_scope = session в конфигурации (pytest.ini/pyproject.toml/setup.cfg).

import pytest
from playwright.async_api import Page

@pytest.mark.asyncio(loop_scope="session")
async def test_foo(page: Page):
await page.goto("https://github.com")
# ...