Pytest 插件参考
简介
Playwright 提供了一个 Pytest 插件来编写端到端测试。要开始使用,请参考 入门指南。
使用方法
要运行你的测试,请使用 Pytest CLI。
pytest --browser webkit --headed
如果你想在不指定参数的情况下自动添加 CLI 参数,可以使用 pytest.ini 文件:
# pytest.ini 的内容
[pytest]
# 在 UI 中运行 Firefox
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)。
夹具(Fixtures)
该插件为 pytest 配置了 Playwright 特定的夹具。要使用这些夹具,请将夹具名称作为参数传递给测试函数。
def test_my_app_is_working(fixture_name):
pass
# 使用 fixture_name 进行测试
# ...
函数作用域: 这些夹具在测试函数请求时创建,并在测试结束时销毁。
context: 为每个测试创建新的浏览器上下文。page: 为每个测试创建新的浏览器页面。new_context: 允许为测试创建不同的浏览器上下文。对于多用户场景非常有用。接受与 browser.new_context() 相同的参数。
会话作用域: 这些夹具在测试函数请求时创建,并在所有测试结束后销毁。
playwright: Playwright 实例。browser_type: 当前浏览器的 BrowserType 实例。browser: Playwright 启动的 Browser 实例。browser_name: 浏览器名称字符串。browser_channel: 浏览器渠道字符串。is_chromium、is_webkit、is_firefox: 各自浏览器类型的布尔值。
自定义夹具选项: 对于 browser 和 context 夹具,使用以下夹具定义自定义启动选项。
browser_type_launch_args: 覆盖 browser_type.launch() 的启动参数。应返回一个字典。browser_context_args: 覆盖 browser.new_context() 的选项。应返回一个字典。
还可以通过使用 browser_context_args 标记为单个测试覆盖上下文选项 (browser.new_context()):
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"]
并行性:同时运行多个测试
如果你的测试运行在具有大量 CPU 的机器上,可以通过使用 pytest-xdist 来加快整体测试执行时间:
# 安装依赖
pip install pytest-xdist
# 使用 --numprocesses 标志
pytest --numprocesses auto
根据硬件和测试性质不同,你可以将 numprocesses 设置为从 2 到机器上的 CPU 数量之间。如果设置过高,你可能会注意到意外的行为。
有关 pytest 选项的一般信息,请参阅 运行测试。
示例
配置自动补全类型
``py title="test_my_application.py" from playwright.sync_api import Page
def test_visit_admin_dashboard(page: Page): page.goto("/admin")
...
如果你使用带有 Pylance 的 VSCode,可以通过启用 `python.testing.pytestEnabled` 设置来推断这些类型,这样就不需要类型注解。
### 使用多个上下文
为了模拟多个用户,你可以创建多个 [`BrowserContext`](./browser-contexts) 实例。
```py title="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 在不同的上下文中
按浏览器跳过测试
import pytest
@pytest.mark.skip_browser("firefox")
def test_visit_example(page):
page.goto("https://example.com")
# ...
在特定浏览器上运行
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
def test_example(page):
page.goto("https://example.com")
配置基础 URL
使用 base-url 参数启动 Pytest。该功能使用 pytest-base-url 插件,允许你从配置、CLI 参数或作为夹具设置基础 URL。
pytest --base-url http://localhost:8080
def test_visit_example(page):
page.goto("/admin")
# -> 将导致 http://localhost:8080/admin
忽略 HTTPS 错误
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"ignore_https_errors": True
}
使用自定义视口大小
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"viewport": {
"width": 1920,
"height": 1080,
}
}
设备模拟 / 浏览器上下文选项覆盖
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"
与 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() 语句来暂停执行并获取 pdb REPL。
def test_bing_is_working(page):
page.goto("https://bing.com")
breakpoint()
# ...
部署到 CI
请参阅 CI 提供商指南 了解如何将测试部署到 CI/CD。
异步夹具
要使用异步夹具,请安装 pytest-playwright-asyncio。
确保你使用的是 pytest-asyncio>=0.26.0 并在配置 (pytest.ini/pyproject.toml/setup.cfg) 中设置 asyncio_default_test_loop_scope = session。
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")
# ...