
关于
使用 Page Object Model、JUnit 5、Allure 报告和并行执行搭建、编写、调试和增强企业级 Playwright Java E2E 测试。
name: playwright-java description: "搭建、编写、调试和增强企业级 Playwright Java E2E 测试,使用 Page Object Model、JUnit 5、Allure 报告和并行执行。" category: test-automation risk: safe source: community date_added: "2025-03-08" author: amalsam18 tags: [playwright, java, e2e-testing, junit5, page-object-model, allure, selenium-alternative] tools: [claude, cursor,antigravity]
Playwright Java – 高级测试自动化
概述
此技能生成生产质量的企业级 Playwright Java 测试代码。 它强制执行 Page Object Model(POM)、严格的定位器策略、线程安全的并行执行和完整的 Allure 报告集成。目标为 Java 17+ 和 Playwright 1.44+。
深入主题的支持参考文件:
| 主题 | 文件 |
|-------|------|
| Maven POM、ConfigReader、Docker/CI 设置 | references/config.md |
| 组件模式、下拉菜单、上传、等待 | references/page-objects.md |
| 完整断言 API、软断言、视觉测试 | references/assertions.md |
| Fixtures、测试数据工厂、认证状态、重试 | references/fixtures.md |
| 即插即用的基类模板 | templates/BaseTest.java、templates/BasePage.java |
何时使用此技能
- 从零搭建新的 Playwright Java 项目时使用
- 编写 Page Object 类或 JUnit 5 测试类时使用
- 用户询问跨浏览器测试、并行执行或 Allure 报告时使用
- 修复不稳定测试或将
Thread.sleep()替换为正确等待时使用 - 在 CI/CD 管道中设置 Playwright(GitHub Actions、Jenkins、Docker)时使用
- 在单个测试中结合 API 调用和 UI 断言(混合测试)时使用
- 用户提到"POM 模式"、"BrowserContext"、"Playwright fixtures"或"traces"时使用
工作原理
步骤 1:确定方法
在编写任何代码之前,使用此矩阵选择正确的模式:
| 用户请求 | 方法 |
|---|---|
| 从零开始的新项目 | 完整脚手架 — 参见 references/config.md |
| 单功能测试 | POM 页面类 + JUnit5 测试类 |
| API + UI 混合 | APIRequestContext 配合 Page |
| 跨浏览器 | @MethodSource 参数化浏览器名称 |
| 不稳定测试修复 | 将 sleep 替换为 waitFor / waitForResponse |
| CI 集成 | 管道中使用 playwright install --with-deps |
| 并行执行 | junit-platform.properties + ThreadLocal |
| 丰富报告 | Allure + Playwright trace + 视频录制 |
步骤 2:搭建项目结构
创建新项目时始终使用此布局:
src/
├── test/
│ ├── java/com/company/tests/
│ │ ├── base/
│ │ │ ├── BaseTest.java ← templates/BaseTest.java
│ │ │ └── BasePage.java ← templates/BasePage.java
│ │ ├── pages/
│ │ │ └── LoginPage.java
│ │ ├── tests/
│ │ │ └── LoginTest.java
│ │ ├── utils/
│ │ │ ├── TestDataFactory.java
│ │ │ └── WaitUtils.java
│ │ └── config/
│ │ └── ConfigReader.java
│ └── resources/
│ ├── test.properties
│ ├── junit-platform.properties
│ └── testdata/users.json
pom.xml
步骤 3:设置线程安全的 BaseTest
public class BaseTest {
protected static ThreadLocal<Playwright> playwrightTL = new ThreadLocal<>();
protected static ThreadLocal<Browser> browserTL = new ThreadLocal<>();
protected static ThreadLocal<BrowserContext> contextTL = new ThreadLocal<>();
protected static ThreadLocal<Page> pageTL = new ThreadLocal<>();
protected Page page() { return pageTL.get(); }
@BeforeEach
void setUp() {
Playwright playwright = Playwright.create();
playwrightTL.set(playwright);
Browser browser = resolveBrowser(playwright).launch(
new BrowserType.LaunchOptions()
.setHeadless(ConfigReader.isHeadless()));
browserTL.set(browser);
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setViewportSize(1920, 1080)
.setRecordVideoDir(Paths.get("target/videos/"))
.setLocale("en-US"));
context.tracing().start(new Tracing.StartOptions()
.setScreenshots(true).setSnapshots(true));
contextTL.set(context);
pageTL.set(context.newPage());
}
@AfterEach
void tearDown(TestInfo testInfo) {
String name = testInfo.getDisplayName().replaceAll("[^a-zA-Z0-9]", "_");
contextTL.get().tracing().stop(new Tracing.StopOptions()
.setPath(Paths.get("target/traces/" + name + ".zip")));
pageTL.get().close();
contextTL.get().close();
browserTL.get().close();
playwrightTL.get().close();
}
private BrowserType resolveBrowser(Playwright pw) {
return switch (System.getProperty("browser", "chromium").toLowerCase()) {
case "firefox" -> pw.fi

