Skip to main content

编写测试

介绍

🌐 Introduction

Playwright 测试很简单,他们

🌐 Playwright tests are simple, they

  • 执行操作,并
  • 在预期中断言状态

在执行操作之前无需等待任何事情:Playwright 会自动等待各种 可操作性 检查通过,然后再执行每个操作。

🌐 There is no need to wait for anything prior to performing an action: Playwright automatically waits for the wide range of actionability checks to pass prior to performing each action.

在进行检查时也不需要处理竞争条件——Playwright 的断言设计的方式是,它们描述了最终需要满足的预期。

🌐 There is also no need to deal with the race conditions when performing the checks - Playwright assertions are designed in a way that they describe the expectations that need to be eventually met.

就是这样!这些设计选择让 Playwright 用户可以完全不用担心测试中的不稳定超时和竞态检查问题。

🌐 That's it! These design choices allow Playwright users to forget about flaky timeouts and racy checks in their tests altogether.

你将学习

第一次测试

🌐 First test

看看下面的示例,了解如何编写测试。注意文件名遵循 test_ 前缀约定,以及每个测试名称的命名方式。

🌐 Take a look at the following example to see how to write a test. Note how the file name follows the test_ prefix convention as well as each test name.

test_example.py
import re
from playwright.sync_api import Page, expect

def test_has_title(page: Page):
page.goto("https://playwright.nodejs.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.nodejs.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()

行动

🌐 Actions

🌐 Navigation

大多数测试将从导航到指定网页 URL 开始。之后,测试将能够与页面元素进行交互。

🌐 Most of the tests will start with navigating page to the URL. After that, test will be able to interact with the page elements.

page.goto("https://playwright.nodejs.cn/")

在继续操作之前,Playwright 会等待页面达到加载状态。了解更多关于 page.goto() 的选项。

🌐 Playwright will wait for page to reach the load state prior to moving forward. Learn more about the page.goto() options.

交互

🌐 Interactions

执行操作首先需要定位元素。Playwright 使用 Locators API 来实现这一点。定位器是一种可以在任何时间找到页面上元素的方法,了解更多关于可用的 不同类型 定位器的信息。Playwright 会在执行操作之前等待元素变为 可操作 状态,因此无需等待元素变得可用。

🌐 Performing actions starts with locating the elements. Playwright uses Locators API for that. Locators represent a way to find element(s) on the page at any moment, learn more about the different types of locators available. Playwright will wait for the element to be actionable prior to performing the action, so there is no need to wait for it to become available.

# Create a locator.
get_started = page.get_by_role("link", name="Get started")

# Click it.
get_started.click()

大多数情况下,它会写成一行:

🌐 In most cases, it'll be written in one line:

page.get_by_role("link", name="Get started").click()

基本动作

🌐 Basic actions

这是最受欢迎的 Playwright 操作列表。请注意,还有更多操作可用,因此请务必查看 Locator API 部分以了解更多信息。

🌐 This is the list of the most popular Playwright actions. Note that there are many more, so make sure to check the Locator API section to learn more about them.

操作描述
locator.check()勾选输入框
locator.click()点击元素
locator.uncheck()取消勾选输入框
locator.hover()鼠标悬停在元素上
locator.fill()填写表单字段,输入文本
locator.focus()聚焦元素
locator.press()按下单个按键
locator.set_input_files()选择要上传的文件
locator.select_option()在下拉菜单中选择选项

断言

🌐 Assertions

Playwright 包含 断言,它们会等待直到满足预期条件。使用这些断言可以使测试不易出错且更具稳健性。例如,这段代码会等待页面标题包含“Playwright”:

🌐 Playwright includes assertions that will wait until the expected condition is met. Using these assertions allows making the tests non-flaky and resilient. For example, this code will wait until the page gets the title containing "Playwright":

import re
from playwright.sync_api import expect

expect(page).to_have_title(re.compile("Playwright"))

这是最流行的异步断言列表。请注意,还有 更多 可供熟悉:

🌐 Here is the list of the most popular async assertions. Note that there are many more to get familiar with:

断言描述
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

测试隔离

🌐 Test isolation

Playwright Pytest 插件基于测试夹具的概念,例如 内置的 page 夹具,它会传入到你的测试中。由于 浏览器上下文,各个测试之间的页面是隔离的,这相当于一个全新的浏览器配置文件,每个测试都会获得一个全新的环境,即使在单个浏览器中运行多个测试也是如此。

🌐 The Playwright Pytest plugin is based on the concept of test fixtures such as the built in page fixture, which is passed into your test. Pages are isolated between tests due to the Browser Context, which is equivalent to a brand new browser profile, where every test gets a fresh environment, even when multiple tests run in a single Browser.

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

🌐 Using fixtures

你可以使用各种夹具在测试之前或之后执行代码,并在测试之间共享对象。例如,带有自动使用(autouse)的 function 作用域夹具的行为类似于 beforeEach/afterEach。而带有自动使用(autouse)的 module 作用域夹具的行为则类似于 beforeAll/afterAll,会在所有测试之前和之后运行。

🌐 You can use various fixtures to execute code before or after your tests and to share objects between them. A function scoped fixture e.g. with autouse behaves like a beforeEach/afterEach. And a module scoped fixture with autouse behaves like a beforeAll/afterAll which runs before all and after all the tests.

test_example.py
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.nodejs.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.nodejs.cn/")

下一步是什么

🌐 What's next