编写测试
简介
Playwright 测试很简单,它们
- 执行操作,并且
- 根据预期断言状态。
在执行操作之前无需等待任何东西:Playwright 会自动等待各种可操作性检查通过,然后才执行每个操作。
在执行检查时也无需处理竞争条件 - Playwright 断言的设计方式是,它们描述了最终需要满足的预期。
就是这样!这些设计选择让 Playwright 用户完全不必担心测试中不稳定的超时和竞争检查。
你将学习
第一个测试
查看以下示例,了解如何编写测试。请注意文件名如何遵循 test_
前缀约定以及每个测试名称。
import re
from playwright.sync_api import Page, expect
def test_has_title(page: Page):
page.goto("https://playwright.net.cn/")
# Expect a title "to contain" a substring.
expect(page).to_have_title(re.compile("Playwright"))
def test_get_started_link(page: Page):
page.goto("https://playwright.net.cn/")
# Click the get started link.
page.get_by_role("link", name="Get started").click()
# Expects page to have a heading with the name of Installation.
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
操作
导航
大多数测试将从导航到 URL 开始。之后,测试将能够与页面元素进行交互。
page.goto("https://playwright.net.cn/")
Playwright 会等待页面达到加载状态,然后才继续。了解更多关于 page.goto() 选项的信息。
交互
执行操作始于定位元素。Playwright 使用定位器 API 来完成。定位器表示在任何时候查找页面上元素的方式,了解更多关于可用不同类型定位器的信息。Playwright 会等待元素可操作后才执行操作,因此无需等待其变为可用。
# Create a locator.
get_started = page.get_by_role("link", name="Get started")
# Click it.
get_started.click()
在大多数情况下,会写在一行中
page.get_by_role("link", name="Get started").click()
基本操作
这是最流行的 Playwright 操作列表。请注意还有更多操作,因此请务必查看定位器 API 部分以了解更多信息。
操作 | 描述 |
---|---|
locator.check() | 勾选输入复选框 |
locator.click() | 点击元素 |
locator.uncheck() | 取消勾选输入复选框 |
locator.hover() | 鼠标悬停在元素上 |
locator.fill() | 填充表单字段,输入文本 |
locator.focus() | 使元素获得焦点 |
locator.press() | 按下单键 |
locator.set_input_files() | 选择要上传的文件 |
locator.select_option() | 在下拉菜单中选择选项 |
断言
Playwright 包含断言,它们会等待直到满足预期条件。使用这些断言可以使测试稳定且具有弹性。例如,此代码将等待直到页面标题包含“Playwright”。
import re
from playwright.sync_api import expect
expect(page).to_have_title(re.compile("Playwright"))
这是最流行的异步断言列表。请注意还有更多断言供您熟悉
测试隔离
Playwright Pytest 插件基于测试 fixture 的概念,例如内置的 page fixture,它被传递到你的测试中。页面由于 Browser Context 而在测试之间隔离,Browser Context 相当于一个全新的浏览器配置文件,每个测试都获得一个全新的环境,即使在单个浏览器中运行多个测试也是如此。
from playwright.sync_api import Page
def test_example_test(page: Page):
pass
# "page" belongs to an isolated BrowserContext, created for this specific test.
def test_another_test(page: Page):
pass
# "page" in this second test is completely isolated from the first test.
使用 fixture
你可以使用各种fixture来在测试之前或之后执行代码并在它们之间共享对象。一个带有 autouse 的 function
范围的 fixture 表现得像 beforeEach/afterEach。而一个带有 autouse 的 module
范围的 fixture 表现得像 beforeAll/afterAll,它在所有测试之前和之后运行。
import pytest
from playwright.sync_api import Page, expect
@pytest.fixture(scope="function", autouse=True)
def before_each_after_each(page: Page):
print("before the test runs")
# Go to the starting url before each test.
page.goto("https://playwright.net.cn/")
yield
print("after the test runs")
def test_main_navigation(page: Page):
# Assertions use the expect API.
expect(page).to_have_url("https://playwright.net.cn/")