关注开源优测不迷路
在测试自动化领域,你可能已经接触过或使用过像Cypress或Selenium这样的工具。
现在,一位新成员登场了,那就是微软推出的Playwright。
你听说过Playwright但还没用过它吗?它与Pytest能很好地集成吗?
你该如何配置它,与Selenium或Cypress相比,为什么你甚至应该考虑使用它呢?
在本文中,我们将回答你关于Playwright的所有问题。
你将了解Playwright与Selenium相比有何不同,它的特点和优势、自动代码生成功能,以及与Pytest的集成方式。
你还将学习如何为浏览器测试截取屏幕截图和录制视频,如何进行并行跨浏览器测试,如何使用跟踪查看器等等。
以上所有内容都配有实际的代码示例。
所以,继续读下去,尽情享受吧。
如果你想直接深入研究代码,这里有一个存储库的链接。
什么是Playwright?
简而言之,自动化测试检查你的应用程序在一个浏览器中或在多个浏览器项目中的运行情况。
它测试当你提交表单、点击按钮、勾选复选框、登录等等操作时会发生什么。
这包括验证页面元素是否按预期加载和运行。
它测试前端与后端进程的交互,并允许你根据预期值来断言页面元素。这可以在你自己的应用程序上进行,甚至也可以在外部应用程序上进行。
微软于2020年1月发布的Playwright是一款新工具,它让你能够轻松地大规模执行自动化测试。
官方文档中是这样描述的:
Playwright支持对现代Web应用程序进行可靠的端到端测试。
它对开发者非常友好(官方文档足以说明这一点),比类似的工具速度快得多,并且具有自动等待、跟踪、屏幕截图和视频录制等内置功能。
它还能在不同的浏览器上下文中运行测试,提供必要的测试隔离,且无需设置清理开销。
我们很快就会谈到它的优势和功能。
Playwright与Selenium的对比
让我们来比较一下Playwright与行业老牌工具Selenium的表现。
架构方面
Playwright:Playwright原生支持多种语言,并提供单一的API来与不同的浏览器协作。它专为并行执行而设计,能够高效处理像单页应用程序这样的现代Web功能。
Selenium:Selenium以一种更传统的、面向对象的方式与页面元素交互,这需要更多的样板代码。它通过WebDriver运行,这可能会引入额外的延迟。
浏览器支持方面
Playwright:原生支持Chromium、Firefox和WebKit项目,无需额外的驱动程序或配置。 Selenium:虽然Selenium支持广泛的浏览器,包括一些不太常见的浏览器,但为不同的浏览器设置驱动程序有时可能会很麻烦。
执行速度方面
Playwright:由于其对现代Web应用程序的更高效处理,以及更自然地运行并行测试的能力,Playwright的执行速度往往更快。
Selenium:与Playwright相比,Selenium通常被认为速度较慢,尤其是在涉及大量AJAX和动态内容的复杂测试场景中。
API和开发者体验方面
Playwright:在支持的语言中提供更一致、统一的API,这可以降低学习曲线,改善开发者体验。
Selenium:Selenium有一个成熟的API,但在不同语言之间略有差异,并且可能比较冗长,执行与Playwright相同的操作需要更多的代码,学习曲线也更陡峭。
设置和配置方面
Playwright:提供更简单的设置,配置开销更少。它还提供了用于生成代码、管理浏览器二进制文件和设置测试环境的工具。
Selenium:可能需要更多的初始设置,尤其是在与各种浏览器集成并管理它们各自的驱动程序时。
持续集成/持续交付(CI/CD)集成方面
Playwright:与现代CI/CD管道无缝集成,并提供跟踪、视频录制和屏幕截图捕获等现成功能。
Selenium:可以集成到CI/CD管道中,但可能需要额外的工具来记录测试和捕获屏幕截图。
Playwright是一款现代工具,在过去四年中逐渐受到关注。
让我们来看看它一些基于优势的功能。
Playwright的优势
为了方便起见,我将列出(并简要解释)官方文档中提到的优势。
任意浏览器 | 任意平台 | 单一API
可在任意浏览器项目上使用——Chromium、Firefox、Webkit
可在Linux、Mac、Windows以及CI/CD管道上运行
API支持Python、Java、Javascript、Typescript和.Net等语言
可原生模拟安卓系统上的Chrome浏览器和Safari浏览器。
可靠 | 测试无不稳定情况
与Selenium不同,在Selenium中你必须手动处理等待元素加载的情况,Playwright会自动处理这一点,这是一个巨大的优势。
基于Web的断言——这意味着Playwright有一个内置的expect语句,例如可以用来断言页面上的元素,如expect(page.get_by_role(“heading”, name=”Installation”)).to_be_visible()。
跟踪——它还具有内置的跟踪功能,允许你生成每次运行的跟踪记录,并将其导入到类似Chrome开发者工具的检查器中。
完全隔离 | 快速执行
Playwright在浏览器上下文中运行每个测试,这相当于在隐身模式下运行一个进程,而不是为每个测试启动一个单独的浏览器。这大大降低了设置和清理的开销。
它还能保存身份验证信息,并可以在多个测试中使用,同时保持完全隔离。
工具
支持 Playwright有出色的工具,如Codegen,它允许你执行操作并生成Playwright测试代码来测试这些元素。
通过跟踪、视频或屏幕捕获来记录测试的能力也确实改变了游戏规则。 官方文档中列出了更多的优势,我们这里只是略窥一二。
我希望你已经相信了Playwright的用例和优势,现在让我们来看一些关于如何使用它的实际代码示例。
使用Playwright——基本示例代码
我们将使用pytest-playwright插件,它为我们提供了内置的Page fixture,并自动处理设置清理和测试隔离,这非常有用。
$ pip install pytest-playwright
接下来,我们安装浏览器套件。
$ playwright install
这将把各种浏览器套件下载到本地机器上。
现在让我们看看简单的Playwright测试。 tests/test_example.py
import pytest
import re
from playwright.sync_api import Page, expect
@pytest.mark.basic
deftest_has_title(page: Page):
page.goto("https://playwright.dev/")
# 期望标题包含一个子字符串。
expect(page).to_have_title(re.compile("Playwright"))
@pytest.mark.basic
deftest_get_started_link(page: Page):
page.goto("https://playwright.dev/")
# 点击“开始”链接。
page.get_by_role("link", name="Get started").click()
# 期望页面有一个名为“安装”的标题。
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
让我们来分析一下这里发生了什么。
我将这些测试标记为“basic”,以便有选择地运行测试,你现在可以先忽略这一点。
我们导入了Playwright提供的Page fixture,它维护测试隔离并处理设置和清理。
我们使用page.goto来访问一个URL。
然后我们使用内置的Web断言expect(page).to_have_title(re.compile("Playwright"))来检查我们访问的页面的标题是否包含“Playwright”或其正则表达式。
在第二个测试中:
我们访问同一个页面。
我们使用get_by_role定位器来定位名为“Get started”的链接并点击它。
我们期望新页面将包含名为“Installation”的标题并且可见。
有几种定位器和操作可用,我们将在本文后面介绍最重要的那些。
让我们运行这些测试。
$ poetry run pytest -m basic
现在我想借此机会介绍一下有头模式和无头模式。
有头模式与无头模式
在测试自动化中,有两种执行模式——有头模式和无头模式。
有头模式意味着测试自动化框架将打开浏览器,并向你展示HTML和执行步骤,这在开发测试和调试时非常方便。
虽然对于本地开发很方便,但在CI/CD管道中这种模式效果并不好。
然而,无头模式意味着在后台运行测试,你不会看到浏览器窗口弹出。但你可以确定它在后台运行并执行必要的步骤。
有头模式的缺点是耗时较长,因此在CI/CD管道或以自动化方式运行测试时,无头模式是首选的操作模式。
Playwright默认以无头模式运行测试,你可以通过向Pytest传递--headed标志来以有头模式运行,从而改变这一设置。
然后你将看到浏览器窗口弹出,运行测试,然后关闭。
$ poetry run pytest -m basic --headed
你可以看到这比无头模式花费的时间要多一些。
示例2
让我们看另一个示例,以了解各种定位器。 tests/test_example.py
@pytest.mark.search
deftest_duckduckgo_search(page: Page):
# 进入DuckDuckGo主页。
page.goto("https://duckduckgo.com/")
# 在搜索框中输入“Pytest with Eric”并按回车键。
page.get_by_placeholder("Search without being tracked").fill("Pytest with Eric")
# 按回车键提交搜索。
page.locator('button[aria-label="Search"]').click()
# 使用get_by_role获取第一个搜索结果
first_result = page.get_by_role("link", name=re.compile("Pytest")).first
# 期望第一个结果包含“Pytest”文本
expect(first_result).to_have_text(re.compile("Pytest With Eric"))
让我们快速浏览一下这里发生了什么。
我们进入DuckDuckGo主页。
我们搜索占位符文本并使用一个查询填充它。
然后我们使用原始的按钮定位器找到搜索按钮并点击它。
我们获取第一个链接并检查它是否包含“Pytest With Eric”。
有几种搜索和验证定位器的方法,这只是其中之一。
运行这个测试:
$ poetry run pytest -m search -v -s
示例3(页面登录)
让我们看另一个稍微复杂一点的示例,在这个示例中你可以登录到一个页面。 tests/test_example.py
@pytest.mark.login
deftest_login(page: Page):
page.goto("https://practicetestautomation.com/practice-test-login/")
# 填写登录表单
page.get_by_label("username").fill("student")
page.get_by_label("password").fill("Password123")
# 提交表单
page.get_by_role("button", name="Submit").click()
# 查找“恭喜消息”文本
expect(page.get_by_text(re.compile("Congratulations"))).to_be_visible()
# 查找“注销”按钮
expect(page.get_by_text(re.compile("Log out"))).to_be_visible()
在这个示例中,我们使用get_by_label定位器获取用户名和密码字段,并使用文本填充它们。
然后我们使用get_by_role定位器获取按钮并点击它。
最后,我们期望页面上有“Congratulations”和“Log out”文本。
$ poetry run pytest -m login -v -s
代码生成(自动生成Playwright代码)
Playwright的一个有趣功能是它能够跟踪你在网页上的操作并自动生成代码(代码生成)。
你可以在这里阅读更多关于此功能的信息。
让我们测试一下。
在终端中,运行:
$ poetry run playwright codegen
这将启动Playwright检查器和一个Chrome浏览器。
点击“录制”按钮(如果它还不是红色的话),然后执行点击按钮、填充元素等操作。
享受在右侧看到自动生成的代码的过程。
在这个示例中,我导航到了https://practicetestautomation.com/practice-test-login/ ,并尝试了不同的登录操作。
结果如下。
很有趣,对吧?你可以从“目标”选择中更改代码语言。
使用xdist进行并行测试
如果你的机器有很多CPU,你可以通过pytest-xdist插件,使用——numprocesses标志来利用Playwright测试的并行执行功能。
$ pytest --numprocesses auto
例如:
使用Playwright截取屏幕截图和录制视频
使用Playwright截取屏幕截图和录制视频也很简单。
屏幕截图
在你的测试中添加以下内容: tests/test_example.py
@pytest.mark.login
deftest_login(page: Page):
page.goto("https://practicetestautomation.com/practice-test-login/")
# 填写登录表单
page.get_by_label("username").fill("student")
page.get_by_label("password").fill("Password123")
# 提交表单
page.get_by_role("button", name="Submit").click()
# 查找“恭喜消息”文本
expect(page.get_by_text(re.compile("Congratulations"))).to_be_visible()
# 查找“注销”按钮
expect(page.get_by_text(re.compile("Log out"))).to_be_visible()
# 截取屏幕截图
page.screenshot(path="screenshot.png")
你可以在这里查看各种配置选项。
视频
让我们调整我们的DuckDuckGo搜索测试以录制视频。 tests/test_example.py
@pytest.mark.search
deftest_duckduckgo_search(page: Page, browser: Browser):
context = browser.new_context(record_video_dir="videos/")
page = context.new_page()
# 进入DuckDuckGo主页。
page.goto("https://duckduckgo.com/")
# 在搜索框中输入“Pytest with Eric”并按回车键。
page.get_by_placeholder("Search without being tracked").fill("Pytest with Eric")
# 按回车键提交搜索。
page.locator('button[aria-label="Search"]').click()
# 使用get_by_role获取第一个搜索结果
first_result = page.get_by_role("link", name=re.compile("Pytest")).first
# 期望第一个结果包含“Pytest”文本
expect(first_result).to_have_text(re.compile("Pytest With Eric"))
# 确保关闭上下文,以便保存视频。
context.close()
让我们梳理一下这些更改:
首先,我们创建了一个新的浏览器上下文,并指定了保存视频的目录。可以把上下文想象成隐身模式。 然后我们在该上下文中创建了一个新页面。 最后,在测试结束时关闭上下文。 结果:
在对应目录我们得到了一个不错的短视频。
跨浏览器测试
任何测试自动化框架的一个重要功能就是在多个浏览器项目上测试你的应用程序。
如今有许多基于不同项目的浏览器——Chromium、Webkit、Firefox等等,你需要确保你的应用程序在所有这些浏览器上都能正常运行。
幸运的是,这也非常简单。
# 在特定浏览器上运行测试
$ pytest test_login.py --browser webkit
# 在多个浏览器上运行测试
$ pytest test_login.py --browser webkit --browser firefox
# 在移动视口上运行测试
$ pytest test_login.py --device="iPhone 13"
# 针对品牌浏览器进行测试,例如微软Edge
$ pytest test_login.py --browser-channel msedge
默认情况下,Playwright将在Chromium上运行你的测试,但你可以指定命令行参数来在不同的浏览器上运行测试。 Playwright跨浏览器测试
跟踪
Playwright让你能够记录跟踪信息,这在调试失败或不稳定的测试(尤其是在CI环境中)时非常有帮助。
这个功能被称为跟踪查看器,你可以通过生成一个trace.zip文件并将其上传到trace.playwright.dev来访问它。
要生成一个跟踪记录,运行:
$ pytest --tracing on
这将生成一个本地跟踪文件(默认在test-results/文件夹中),但你可以更改文件名和位置。
接下来,导航到trace.playwright.dev并上传你的trace.zip文件。
你可以像这样查看跟踪记录:
这使你能够回顾测试过程,了解底层发生了什么。当与屏幕截图和视频结合使用时,这无疑是调试失败或不稳定测试的强大方法。
结论
关于Playwright,我们还有很多可以讨论的内容——Pytest fixture、模拟、API测试、定位器的类型等等。
然而,由于时间和篇幅的限制,我决定在这里结束这篇文章。
如果你希望我写更多关于Playwright的一些有趣功能的内容,请留言或关注加我微信。
在本文中,我们首先比较了行业老牌工具Selenium和Playwright。
然后你了解了Playwright的优势,包括基于Web的断言、自动等待和定位器。
接着我们看到了一些如何使用Playwright编写测试的实际代码示例,有头模式与无头模式的区别,以及截取屏幕截图、录制视频和跟踪的方法。
我希望你觉得这篇文章有用,并受到启发,无论是在工作中还是在你自己的项目里,都愿意开始使用Playwright。
我认为它是一款非常强大且现代化的自动化工具,并且有着出色的文档支持。
如果你还希望对这段译文进行修改,或者有其他的翻译、写作等方面的需求,随时都可以告诉我。