Java 如何把 Playwright 接入 JUnit 5 测试并使用 @UsePlaywright 注入 Page 夹具?
【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright
如果你的 Java 项目正在用 JUnit 5(Jupiter)做端到端测试,又不想在每个测试类里手写Playwright.create()、browser.newContext()、context.close()这一套生命周期代码,Playwright 提供了一组 JUnit 夹具:在测试类上加上@UsePlaywright注解,测试方法里声明Page page参数,框架就会自动初始化 Playwright、Browser、BrowserContext 和 Page,并在测试结束后清理。这个集成在文档中的标题是 “JUnit (experimental)”,于 Playwright Java 1.42 版本引入,属于实验功能(见 Release notes 与 JUnit 指南)。本文的主路径是 Maven 项目;Gradle 的差异在后面单独说明。
适用前提(来自 Installation 文档):
- Java 8 或更高版本;
- 操作系统为 Windows 11+ / Windows Server 2019+ / WSL、macOS 14 (Sonoma) 或更高、Debian 12/13、Ubuntu 22.04/24.04/26.04(x86-64 或 arm64);
- 项目使用 JUnit 5,测试方法使用
org.junit.jupiter.api.Test注解。
声明 Maven 依赖
Playwright 以 Maven 模块分发,最简接入方式是在pom.xml的dependencies中添加一个依赖。Installation 文档 给出的完整示例如下,其中的%%VERSION%%是文档里的模板占位符,需要替换为你要使用的 Playwright 具体版本号(本仓库当前package.json中的版本为1.64.0-next,可参考仓库实际发布版本选择):
<dependencies> <dependency> <groupId>com.microsoft.playwright</groupId> <artifactId>playwright</artifactId> <version>%%VERSION%%</version> <!-- 替换为你要使用的 Playwright 版本号 --> </dependency> </dependencies>文档同时建议配置maven-compiler-plugin3.10.1,source/target设为 1.8,并注释说明“对接口静态方法的引用要求 source level 1.8 以上”:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>如果项目使用 Gradle,Test Runners 文档 给出了对应的build.gradle(Groovy)配置:依赖com.microsoft.playwright:playwright:%%VERSION%%(同样是需替换的版本占位符),repositories配置mavenCentral(),并在test块中声明useJUnitPlatform(),这样 Gradle 才会用 JUnit 5 平台执行测试。
浏览器二进制:首次运行自动下载,也可显式安装
Playwright 每个版本需要特定版本的浏览器二进制文件。按 Installation 文档,首次编译运行程序时会“下载 Playwright 包并安装 Chromium、Firefox 和 WebKit 的浏览器二进制”——即首次跑起来时浏览器会自动就位。
如果需要显式安装(例如升级 Playwright 后需要重新执行安装,见 Browsers 文档),Java 下使用 Maven 调用 Playwright CLI:
mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install"不带参数时安装默认浏览器集;也可以指定单个浏览器,例如install webkit:
mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install webkit"想查看支持的全部浏览器,把参数换成install --help即可。这条命令只安装浏览器二进制,不影响已有测试代码。
用 @UsePlaywright 写入第一个测试
在测试类上加@UsePlaywright,测试方法的参数就“告诉 JUnit 设置对应的夹具并提供给测试方法”。JUnit 指南 的完整示例(可直接作为src/test/java下的测试类,断言即验证点):
package org.example; import com.microsoft.playwright.Page; import com.microsoft.playwright.junit.UsePlaywright; import org.junit.jupiter.api.Test; import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @UsePlaywright public class TestExample { @Test void shouldClickButton(Page page) { page.navigate("data:text/html,<script>var result;</script><button onclick='result=\"Clicked\"'>Go</button>"); page.locator("button").click(); assertEquals("Clicked", page.evaluate("result")); } @Test void shouldCheckTheBox(Page page) { page.setContent("<input id='checkbox' type='checkbox'></input>"); page.locator("input").check(); assertEquals(true, page.evaluate("window['checkbox'].checked")); } @Test void shouldSearchWiki(Page page) { page.navigate("https://www.wikipedia.org/"); page.locator("input[name=\"search\"]").click(); page.locator("input[name=\"search\"]").fill("playwright"); page.locator("input[name=\"search\"]").press("Enter"); assertThat(page).hasURL("https://en.wikipedia.org/wiki/Playwright"); } }注意示例中三条测试方法共用同一个Browser(每个类里的测试方法共享 Browser 以优化资源),但每条测试拥有自己的BrowserContext和Page,浏览器状态在测试之间是隔离的。shouldSearchWiki访问外网,如果你的环境无法访问wikipedia.org,可只保留前两个本地用例验证接入是否成功。
可用的预定义夹具
文档列出的夹具及作用(来源):
| Fixture | Type | Description |
|---|---|---|
| page | Page | Isolated page for this test run. |
| browserContext | BrowserContext | Isolated context for this test run. Thepagefixture belongs to this context as well. |
| browser | Browser | Browsers are shared across tests to optimize resources. |
| playwright | Playwright | Playwright instance is shared between tests running on the same thread. |
| request | APIRequestContext | Isolated APIRequestContext for this test run. |
也就是说,方法签名里声明哪个类型,框架就注入哪个夹具;page、browserContext、browser、playwright、request都可作为参数出现。
结果验证
文档没有给出一段固定的成功日志,验证方式就是测试断言本身:
assertEquals("Clicked", page.evaluate("result")):点击后页面变量result应等于"Clicked",不满足则该测试失败;assertThat(page).hasURL("https://en.wikipedia.org/wiki/Playwright"):使用 Playwright 的 web-first 断言校验最终 URL;assertThat(page).hasTitle(Pattern.compile("Playwright")):校验页面标题匹配正则(文档 Fixtures 章节的例子)。
用你的构建工具执行测试(Gradle 项目在test { useJUnitPlatform() }配置下通过 Gradle 的测试任务运行;Maven 走标准的test任务),测试全部通过、无失败断言,即说明@UsePlaywright夹具链路工作正常。浏览器未安装时测试会在启动浏览器环节失败,此时先执行上一节的install命令。
可选:用 OptionsFactory 定制夹具选项
默认夹具不满足时(比如要 headful 运行、或给页面/API 请求设置 baseURL),实现OptionsFactory接口并把类写进@UsePlaywright()注解即可覆盖 [BrowserType.launch] 的启动选项、Browser.newContext的上下文选项和APIRequest.newContext的选项(来源):
import com.microsoft.playwright.junit.Options; import com.microsoft.playwright.junit.OptionsFactory; import com.microsoft.playwright.junit.UsePlaywright; @UsePlaywright(MyTest.CustomOptions.class) public class MyTest { public static class CustomOptions implements OptionsFactory { @Override public Options getOptions() { return new Options() .setHeadless(false) .setContextOption(new Browser.NewContextOptions() .setBaseURL("https://github.com")) .setApiRequestOptions(new APIRequest.NewContextOptions() .setBaseURL("https://playwright.dev")); } } @Test public void testWithCustomOptions(Page page, APIRequestContext request) { page.navigate("/"); assertThat(page).hasURL(Pattern.compile("github")); APIResponse response = request.get("/"); assertTrue(response.text().contains("Playwright")); } }要点:setHeadless(false)让浏览器带 UI 启动;setContextOption里的baseURL让page.navigate("/")这类相对路径生效;setApiRequestOptions单独控制request夹具的 baseURL。文档示例的断言是:访问/后 URL 匹配github,对request发起 GET 后响应文本包含"Playwright",可照此校验定制是否生效。
可选:并行运行多个测试类
JUnit 默认单线程顺序执行所有测试;自 JUnit 5.3 起可改为并行执行。文档同时提醒:不加同步就从多个线程使用同一个 Playwright 对象是不安全的,推荐每个线程创建并独占一个 Playwright 实例(来源)。使用@UsePlaywright时,文档给出的示例就是多个测试类各自标注@UsePlaywright(前文的TestExample即为一个,文档另配了一个含shouldReturnInnerHTML、shouldClickButton两个用例的Test2类)。
让“类内顺序、类间并行,最大线程数取 CPU 核心数的一半”,在 JUnit 配置中设置:
junit.jupiter.execution.parallel.enabled = true junit.jupiter.execution.parallel.mode.default = same_thread junit.jupiter.execution.parallel.mode.classes.default = concurrent junit.jupiter.execution.parallel.config.strategy=dynamic junit.jupiter.execution.parallel.config.dynamic.factor=0.5如果不用@UsePlaywright而是手动管理生命周期,Test Runners 文档 的并行方案是:基类加@TestInstance(TestInstance.Lifecycle.PER_CLASS),把Playwright、Browser存为实例字段并在@BeforeAll/@AfterAll中创建/关闭,每个测试类继承该基类,从而“每个类实例拥有自己的 Playwright 副本”。
限制与注意事项
- 该集成目前是实验功能(文档标题即 “JUnit (experimental)”),API 可能在后续版本调整,跟进 Release notes 中的相关说明。
- 文档示例中的外部站点(
wikipedia.org、playwright.dev、github.com)需要网络可达,离线环境下请改用data:text/html或page.setContent(...)类的本地用例(文档示例已包含这类离线写法)。 %%VERSION%%是文档模板占位符而非真实版本号,写入pom.xml/build.gradle前必须替换,否则构建会直接失败。- 升级 Playwright 版本后,浏览器二进制可能需要同步重装,按 Browsers 文档 的说法每次更新 Playwright 后“可能需要重新运行
install命令”。
进一步阅读:手动生命周期写法(@BeforeAll/@AfterAll方案)见 Running and debugging tests,测试运行器与 TestNG 对照见 Test Runners。
【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考