目录
介绍
Playwright 测试非常简单,它们
- 执行操作,
- 并断言状态是否符合预期。
在执行任何操作之前,无需等待任何内容:Playwright 在执行每个操作之前会自动等待一系列可操作性检查通过。
此外,在执行检查时也不需要处理竞态条件------Playwright 的断言设计方式能够描述最终需要满足的期望。
就这样!这些设计选择允许 Playwright 用户完全忘记他们测试中的不稳定超时和竞态检查。
您将学习
- 如何编写第一个测试
- 如何执行操作
- 如何使用断言
- 测试如何在隔离环境中运行
- 如何使用测试钩子
第一个测试
请查看以下示例,了解如何编写测试。请注意文件名如何遵循以 test_
为前缀的约定,以及每个测试名称的命名方式。
# test_example.py
import re
from playwright.sync_api import Page, expect
def test_has_title(page: Page):
page.goto("https://playwright.dev/")
# 期待标题"包含"一个子字符串。
expect(page).to_have_title(re.compile("Playwright"))
def test_get_started_link(page: Page):
page.goto("https://playwright.dev/")
# 点击"开始使用"链接。
page.get_by_role("link", name="Get started").click()
# 期待页面有一个标题为"Installation"的标题。
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
定义了两个测试函数,分别用于检查 Playwright 官网的标题和点击"开始使用"链接后的页面内容。
-
test_has_title
函数通过page.goto
方法导航到 Playwright 官网,并使用expect(page).to_have_title
方法来检查页面标题是否包含"Playwright"这个子字符串。这里使用了正则表达式re.compile("Playwright")
来匹配标题。 -
test_get_started_link
函数同样先导航到 Playwright 官网,然后使用page.get_by_role
方法找到"开始使用"链接(假设该链接的角色是"link"且其名称是"Get started"),并执行点击操作。之后,再次使用page.get_by_role
方法找到标题为"Installation"的标题,并使用expect(...).to_be_visible
方法来检查该标题是否可见。这验证了点击"开始使用"链接后,用户被正确地导航到了安装指南页面。
操作
导航
大多数测试将从将页面导航到URL开始。之后,测试将能够与页面元素进行交互。
page.goto("https://playwright.dev/")
Playwright 将在继续之前等待页面达到加载状态。了解更多关于page.goto() 选项的信息。
交互(Interactions)
执行操作始于定位元素。Playwright 使用 Locators API来实现这一点。Locator 表示在任何时刻在页面上查找元素(或多个元素)的一种方式,了解更多关于可用的不同类型 Locator 的信息。Playwright 将在执行操作之前等待元素变为可操作状态actionable,因此无需等待它变为可用状态。
# 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来定位页面上角色(role)为"link",且其名称(name)为"Get started"的链接元素,并对该元素执行点击(click)操作。
基本操作
这是Playwright中最常用的操作列表。请注意,还有更多其他操作,因此请确保查阅Locator 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"))
以下是最常用的异步断言列表。请注意,还有更多其他断言需要熟悉:
断言 | 描述 |
---|---|
expect(locator).to_be_checked() | 复选框被选中 |
expect(locator).to_be_enabled() | 控件被启用 |
expect(locator).to_be_visible() | 元素可见 |
expect(locator).to_contain_text() | 元素包含文本 |
expect(locator).to_have_attribute() | 元素具有某个属性 |
expect(locator).to_have_count() | 元素列表具有给定长度 |
expect(locator).to_have_text() | 元素匹配文本 |
expect(locator).to_have_value() | 输入元素具有值 |
expect(page).to_have_title() | 页面具有标题 |
expect(page).to_have_url() | 页面具有URL |
测试隔离
Playwright的Pytest插件基于测试夹具(fixtures)的概念,如内置的页面夹具(page fixture),它会被传递到您的测试中。由于浏览器上下文(Browser Context)的存在,测试之间的页面是隔离的。浏览器上下文相当于一个新的浏览器配置文件,每个测试都会获得一个全新的环境,即使在单个浏览器中运行多个测试也是如此。
test_example.py
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.
使用夹具(Fixtures)
您可以使用各种夹具(fixtures)在测试之前或之后执行代码,并在它们之间共享对象。一个函数作用域的夹具(如使用autouse=True
)表现得像beforeEach/afterEach
。而一个模块作用域的夹具(也使用autouse=True
)则表现得像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("测试运行之前")
# 在每个测试之前跳转到起始URL
page.goto("https://playwright.dev/")
yield # yield 语句之后的代码会在测试函数执行完毕后执行
print("测试运行之后")
def test_main_navigation(page: Page):
# 使用 expect API 进行断言
expect(page).to_have_url("https://playwright.dev/")