跳到主要內容

測試執行器

簡介

只需幾行程式碼,您就可以將 Playwright 連接到您最喜愛的 Java 測試執行器。

Playwright 和瀏覽器實例可以在測試之間重複使用,以獲得更好的效能。我們建議在新的瀏覽器情境中執行每個測試案例,這樣瀏覽器狀態將在測試之間隔離。

JUnit

JUnit 中,您可以在 @BeforeAll 方法中初始化 PlaywrightBrowser,並在 @AfterAll 中銷毀它們。在下面的範例中,所有三個測試方法都使用相同的 Browser。每個測試都使用自己的 BrowserContextPage

package org.example;

import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import org.junit.jupiter.api.*;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class TestExample {
// Shared between all tests in this class.
static Playwright playwright;
static Browser browser;

// New instance for each test method.
BrowserContext context;
Page page;

@BeforeAll
static void launchBrowser() {
playwright = Playwright.create();
browser = playwright.chromium().launch();
}

@AfterAll
static void closeBrowser() {
playwright.close();
}

@BeforeEach
void createContextAndPage() {
context = browser.newContext();
page = context.newPage();
}

@AfterEach
void closeContext() {
context.close();
}

@Test
void shouldClickButton() {
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.setContent("<input id='checkbox' type='checkbox'></input>");
page.locator("input").check();
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
}

@Test
void shouldSearchWiki() {
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");
assertEquals("https://en.wikipedia.org/wiki/Playwright", page.url());
}
}

請參閱實驗性的 JUnit 整合,以自動初始化 Playwright 物件以及更多。

平行執行測試

預設情況下,JUnit 將在單一執行緒上依序執行所有測試。自 JUnit 5.3 起,您可以變更此行為以平行執行測試,以加快執行速度 (請參閱 此頁面)。由於在沒有額外同步的情況下,從多個執行緒使用相同的 Playwright 物件並不安全,因此我們建議您為每個執行緒建立 Playwright 實例,並在該執行緒上獨佔使用它。以下是如何平行執行多個測試類別的範例。

使用 @TestInstance(TestInstance.Lifecycle.PER_CLASS) 註解,使 JUnit 為該類別中的所有測試方法建立一個類別實例 (預設情況下,每個 JUnit 都會為每個測試方法建立一個新的類別實例)。將 PlaywrightBrowser 物件儲存在實例欄位中。它們將在測試之間共用。該類別的每個實例都將使用自己的 Playwright 副本。

// Subclasses will inherit PER_CLASS behavior.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestFixtures {
// Shared between all tests in the class.
Playwright playwright;
Browser browser;

@BeforeAll
void launchBrowser() {
playwright = Playwright.create();
browser = playwright.chromium().launch();
}

@AfterAll
void closeBrowser() {
playwright.close();
}

// New instance for each test method.
BrowserContext context;
Page page;

@BeforeEach
void createContextAndPage() {
context = browser.newContext();
page = context.newPage();
}

@AfterEach
void closeContext() {
context.close();
}
}

class Test1 extends TestFixtures {
@Test
void shouldClickButton() {
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.setContent("<input id='checkbox' type='checkbox'></input>");
page.locator("input").check();
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
}

@Test
void shouldSearchWiki() {
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");
assertEquals("https://en.wikipedia.org/wiki/Playwright", page.url());
}
}

class Test2 extends TestFixtures {
@Test
void shouldReturnInnerHTML() {
page.setContent("<div>hello</div>");
assertEquals("hello", page.innerHTML("css=div"));
}

@Test
void shouldClickButton() {
Page popup = page.waitForPopup(() -> {
page.evaluate("window.open('about:blank');");
});
assertEquals("about:blank", popup.url());
}
}

設定 JUnit 以依序執行每個類別中的測試,並在平行執行緒上執行多個類別 (最大執行緒數等於 CPU 核心數的 1/2)

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

使用 Gradle

您可以使用以 Groovy 或 Kotlin 撰寫的 Gradle 建置組態腳本。

plugins {
application
id 'java'
}

repositories {
mavenCentral()
}

dependencies {
implementation 'com.microsoft.playwright:playwright:1.49.0'
}

application {
mainClass = 'org.example.App'
}

// Usage: ./gradlew playwright --args="help"
task playwright(type: JavaExec) {
classpath sourceSets.test.runtimeClasspath
mainClass = 'com.microsoft.playwright.CLI'
}

test {
useJUnitPlatform()
}

然後可以如下所示啟動測試

./gradlew run

此外,Playwright 命令列工具可以使用以下方式執行

./gradlew playwright --args="help"

TestNG

TestNG 中,您可以在 @BeforeClass 方法中初始化 PlaywrightBrowser,並在 @AfterClass 中銷毀它們。在下面的範例中,所有三個測試方法都使用相同的 Browser。每個測試都使用自己的 BrowserContextPage

package org.example;

import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import org.testng.annotations.*;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

public class TestExample {
// Shared between all tests in this class.
Playwright playwright;
Browser browser;

// New instance for each test method.
BrowserContext context;
Page page;

@BeforeClass
void launchBrowser() {
playwright = Playwright.create();
browser = playwright.chromium().launch();
}

@AfterClass
void closeBrowser() {
playwright.close();
}

@BeforeMethod
void createContextAndPage() {
context = browser.newContext();
page = context.newPage();
}

@AfterMethod
void closeContext() {
context.close();
}

@Test
void shouldClickButton() {
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.setContent("<input id='checkbox' type='checkbox'></input>");
page.locator("input").check();
assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked"));
}

@Test
void shouldSearchWiki() {
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");
assertEquals("https://en.wikipedia.org/wiki/Playwright", page.url());
}
}