Playwright
playwright出自名门,是微软研发团队所开发的一款Web自动化测试框架,发布于2020年初。
Playwright 是专门为了满足端到端测试的需求而创建的库。Playwright 支持所有现代渲染引擎,包括 Chromium、WebKit 和 Firefox。在 Windows、Linux 和 macOS 上进行本地或 CI 测试,无头测试或使用本机移动模拟进行测试。
主要特点
- Any browser • Any platform • One API
跨浏览器:支持chromium、webkit、Firefox
跨平台:支持windows、linux、macos、locallly、CI、headless、headed
跨语言:Typescript、JS、python、java、.NET
支持移动web:支持chrome原生APP androidhe safari模拟。
-Resilient • No flaky tests
自动等待:不需要人为定义等待
web优先断言:playwright的断言专门为动态网站设计。检查会自动重试,直到满足条件。
追踪:支持截图,录制视频、录制执行跟踪。
-No trade-offs • No limits
Playwright 与现代浏览器架构保持一致,并在进程外运行测试
多种一切。跨多个选项卡、多个源和多个用户的测试方案。为不同的用户创建具有不同上下文的方案,并针对您的服务器运行它们,所有这些都在一个测试中完成。
受信任的事件。悬停元素,与动态控件交互,生成受信任的事件。剧作家使用与真实用户无法区分的真实浏览器输入管道。
测试帧,刺穿暗影 DOM。剧作家选择器刺穿阴影 DOM,并允许无缝进入帧。
-Full isolation • Fast execution
浏览器上下文。为每个测试创建一个浏览器上下文。浏览器上下文等效于全新的浏览器配置文件。这提供了完全的测试隔离,零开销。创建新的浏览器上下文只需几毫秒。
登录一次。保存上下文的身份验证状态,并在所有测试中重用它。这绕过了每个测试中的重复登录操作,但提供了独立测试的完全隔离。
-Powerful Tooling
录制操作 通过记录操作来生成测试。将它们保存为任何语言。
inspector 检查页面,生成选择器,逐步执行测试,查看单击点,浏览执行日志。
跟踪查看器。捕获所有信息以调查测试失败。Playwright 跟踪包含测试执行截屏视频、实时 DOM 快照、操作资源管理器、测试源等。
- 支持异步、非阻塞API,允许在单个页面上执行多个操作。
- 支持网络拦截器,可以拦截和修改HTTP请求和响应。
- 支持录制和重放交互式测试,可以记录并播放用户交互过程。
-支持python、nodejs、java、.NET
Playwright是一个功能强大的自动化工具,可用于测试和自动化浏览器,它提供了一个易于使用的API和各种功能,可以大大提高测试和自动化的效率和可靠性。
官方文档:Installation | Playwright Python
vs selenium
Playwright和Selenium是两种常用的自动化测试工具,它们都可以对Web应用进行自动化测试,但在某些方面存在差异。
1. 支持浏览器:Playwright支持Chrome、Firefox、Safari和Edge浏览器;Selenium支持这些浏览器以及IE和Opera。
2. 多浏览器并行测试:Playwright可以在多个浏览器中并行运行测试,而Selenium默认情况下只允许在一个浏览器中运行测试。
3. 稳定性:Playwright设计时考虑了一些Selenium没有考虑到的问题,比如可以自动等待元素,如稳定性和可靠性。Playwright使用自己的浏览器驱动程序,可以解决某些Selenium驱动程序在不同浏览器版本中出现的错误。
4. 速度:Playwright在许多方面比Selenium更快,比如启动和关闭浏览器、执行操作等。
5. 语法:Playwright使用异步API,而Selenium使用同步API。异步API可以使测试脚本更简洁,同时更快地执行操作。
总的来说,Playwright和Selenium都是非常强大的自动化测试工具,具有各自的优缺点。选择哪一个工具取决于您的需求和项目要求。
安装
Playwright 建议使用官方Playwright Pytest 插件来编写端到端测试。它提供上下文隔离,开箱即用地在多个浏览器配置上运行。
也可以直接使用 playwright库 Getting started - Library | Playwright Python
Pytest 插件使用 Playwright 的同步版本,还有一个可通过库访问的异步版本。
首先安装 Playwright 并运行示例测试以查看其实际情况。
安装Pytest 插件:
pip install pytest-playwright
安装所需的浏览器:
playwright install
第一个demo
import re
from playwright.sync_api import Page, expect
def test_homepage_has_Playwright_in_title_and_get_started_link_linking_to_the_intro_page(page: Page):
page.goto("https://playwright.dev/")
# Expect a title "to contain" a substring.
expect(page).to_have_title(re.compile("Playwright"))
# create a locator
get_started = page.get_by_role("link", name="Get started")
# Expect an attribute "to be strictly equal" to the value.
expect(get_started).to_have_attribute("href", "/docs/intro")
# Click the get started link.
get_started.click()
# Expects the URL to contain intro.
expect(page).to_have_url(re.compile(".*intro"))
默认情况下,测试将在 Chromium 上运行。这可以通过 CLI 选项进行配置。测试在无头模式下运行,这意味着运行测试时不会打开浏览器 UI。测试结果和测试日志将显示在终端中。
pytest
(在terminal输入pytest 文件名运行测试)
系统要求
- Python 3.8 or higher.
- Windows 10+, Windows Server 2016+ or Windows Subsystem for Linux (WSL).
- MacOS 12 Monterey or MacOS 13 Ventura.
- Debian 11, Ubuntu 20.04 or Ubuntu 22.04.
断言
playwright断言是专门为动态网络创建的。检查会自动重试,直到满足必要的条件。内置自动等待功能这意味着它会在执行操作之前等待元素可操作。
提供了期望功能,它将等待到满足预期条件。
import re
from playwright.sync_api import expect
expect(page).to_have_title(re.compile("Playwright"))
测试挂钩
您可以使用各种夹具在测试之前或之后执行代码,并在它们之间共享对象。一个示波范围的夹具,例如具有自动使用功能的行为类似于之前每个/之后每个。具有自动使用功能的范围夹具的行为类似于在所有测试之前和之后运行的所有/之后。function
module
import pytest
from playwright.sync_api import Page
@pytest.fixture(scope="function", autouse=True)
def before_each_after_each(page: Page):
print("beforeEach")
# Go to the starting url before each test.
page.goto("https://playwright.dev/")
yield
print("afterEach")
def test_main_navigation(page: Page):
# Assertions use the expect API.
expect(page).to_have_url("https://playwright.dev/")
本质就是pytest的fixture功能,可以根据范围使用fixture。
运行测试
可以运行单个测试、一组测试或所有测试。测试可以在一个浏览器或多个浏览器上运行。默认情况下,测试以无头方式运行,这意味着在运行测试时不会打开浏览器窗口,结果将在终端中看到。如果您愿意,可以使用标志在有头模式下运行测试
-
Running tests on Chromium
pytest
-
运行单个测试文件
pytest test_login.py
-
运行一组测试文件
pytest tests/todo-page/ tests/landing-page/
-
使用函数名称运行测试
pytest -k "test_add_a_todo_item"
-
在定向模式下运行测试
pytest --headed test_login.py
默认是无头模式,使用--headed参数可以开启有头模式浏览器 -
在特定浏览器上运行测试
pytest test_login.py --browser webkit
-
在多个浏览器上运行测试
pytest test_login.py --browser webkit --browser firefox
-
并行运行测试
pytest --numprocesses auto
(这假定已安装。有关更多信息,请参阅此处。
pytest-xdist
有关更多信息,请参阅 Playwright Pytest 用法或 Pytest 文档了解常规 CLI 用法。
基于pytest的插件
playwright提供了一些基于pytest的高级功能
命令行参数
--headed
:以定向模式运行测试(默认:无外设)。--browser
:在不同的浏览器 、 或 中运行测试。可以多次指定(默认值:)。chromium
firefox
webkit
chromium
--browser-channel
要使用的浏览器通道。--slowmo
将剧作家操作减慢指定的毫秒数。很有用,以便您可以看到正在发生的事情(默认值: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
配置慢动作
使用参数运行慢速测试。--slowmo
pytest --slowmo 100
将剧作家操作减慢 100 毫秒。
通过浏览器跳过测试
@pytest.mark.skip_browser("chromium")
def test_baidu(page: Page):
# Assertions use the expect API.
page.goto("http://www.baidu.com")
使用装饰器指定在该浏览器上不运行这条用例
可以看到一条通过,一条跳过。
在特定浏览器上运行
conftest.py
import pytest
@pytest.mark.only_browser("chromium")
def test_visit_example(page):
page.goto("https://example.com")
# ...
使用自定义浏览器
(如谷歌浏览器或Microsoft Edge)运行
pytest --browser-channel chrome
test_my_application.py
def test_example(page):
page.goto("https://example.com")
默认使用chromium运行,使用该命令后,指定使用chrome运行。
配置base-url
使用参数启动 Pytest。pytest-base-url 插件用于允许您从配置、CLI 参数或作为固定装置设置基本 url 的插件。base-url
pytest --base-url http://localhost:8080
def test_visit_example(page):
page.goto("/admin")
# -> Will result in 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,
}
}
在conftest里实现该方法
设备仿真
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,
}
或通过命令行界面--device="iPhone 11 Pro"
模拟iphone11pro设备大小
持久上下文
conftest.py
import pytest
from playwright.sync_api import BrowserType
from typing import Dict
@pytest.fixture(scope="session")
def context(
browser_type: BrowserType,
browser_type_launch_args: Dict,
browser_context_args: Dict
):
context = browser_type.launch_persistent_context("./foobar", **{
**browser_type_launch_args,
**browser_context_args,
"locale": "de-DE",
})
yield context
context.close()
使用它时,测试中的所有页面都是从持久上下文创建的。
调试
与 pdb 一起使用
使用测试代码中的语句暂停执行并获取 pdb REPL。breakpoint()
def test_bing_is_working(page):
page.goto("https://bing.com")
breakpoint()
# ...
在需要插入断点的地方调用breakpoint()方法,使用正常运行模式,程序运行至该点时,就会停止运行,可以进行调试操作,不需要像selenium里进行手动sleep了。
使用unittest
这有一个限制,即只能指定单个浏览器,并且在指定多个浏览器时不会生成多个浏览器的矩阵。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
部署到 CI
请参阅 CI 提供程序将测试部署到 CI/CD 的指南。
测试生成器
录制操作
使用该命令运行测试生成器,后跟要为其生成测试的网站的 URL。URL 是可选的,您始终可以在没有它的情况下运行命令,然后将 URL 直接添加到浏览器窗口中
在pycharm的terminal输入
playwright codegen demo.playwright.dev/todomvc
会打开默认的Chromium浏览器和playwright inspector。
在浏览器中运行和执行操作,playwright将为用户交互生成代码。 将查看呈现的页面并找出建议的定位器,确定角色、文本和测试 ID 定位器的优先级。如果生成器识别出与定位器匹配的多个元素,它将改进定位器,使其具有弹性并唯一地标识目标元素,从而消除和减少由于定位器而导致的测试失败和剥落。
打开百度网址,输入周杰伦,点击百度一下,生成代码如下
生成定位器
您可以使用测试生成器生成定位器。
- 在inspector按下按钮停止录制,按钮将出现。
'Record'
'Pick Locator'
- 单击该按钮,然后将鼠标悬停在浏览器窗口中的元素上,以查看每个元素下方突出显示的定位器。
'Pick Locator'
- 要选择定位器,请单击要定位的元素,该定位器的代码将显示在“选取定位器”按钮旁边的字段中。
- 然后,您可以编辑此字段中的定位器以对其进行微调,或使用复制按钮将其复制并粘贴到代码中。
点击pick locator,在页面拾取元素,生成定位表达式。
跟踪查看器
Playwright Trace Viewer 是一个 GUI 工具,可以探索记录的 Playwright 测试跟踪,这意味着可以来回浏览测试的每个操作,并直观地查看每个操作期间发生的情况。
记录跟踪
可以使用 browser_context.tracing API 记录跟踪,如下所示:
- 同步
browser = chromium.launch()
context = browser.new_context()
# Start tracing before creating / navigating a page.
context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = context.new_page()
page.goto("https://playwright.dev")
# Stop tracing and export it into a zip archive.
context.tracing.stop(path = "trace.zip")
- 异步
browser = await chromium.launch()
context = await browser.new_context()
# Start tracing before creating / navigating a page.
await context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = await context.new_page()
await page.goto("https://playwright.dev")
# Stop tracing and export it into a zip archive.
await context.tracing.stop(path = "trace.zip")
这将记录跟踪并将其放入名为 的文件中。trace.zip
打开跟踪
使用 Playwright CLI 或在 trace.playwright.dev 的浏览器中打开保存的跟踪。
playwright show-trace trace.zip
查看跟踪
通过单击每个操作或使用时间线悬停来查看测试的跟踪,并查看操作前后页面的状态。在测试的每个步骤中检查日志、源和网络。跟踪查看器会创建一个 DOM 快照,以便可以与其完全交互、打开开发工具等。