JUnit(实验性)
介绍
🌐 Introduction
只需几行代码,你就可以将 Playwright 连接到你最喜欢的 Java 测试运行器。
🌐 With a few lines of code, you can hook up Playwright to your favorite Java test runner.
在 JUnit 中,你可以使用 Playwright fixtures 来自动初始化 Playwright、Browser、BrowserContext 或 Page。在下面的示例中,所有三个测试方法都使用相同的 Browser。每个测试使用它自己独立的 BrowserContext 和 Page。
🌐 In JUnit, you can use Playwright fixtures to automatically initialize Playwright, Browser, BrowserContext or Page. In the example below, all three test methods use the same Browser. Each test uses its own BrowserContext and Page.
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");
}
}
夹具
🌐 Fixtures
只需在你的测试类中添加 JUnit 注解 @UsePlaywright 就可以启用 Playwright 夹具。测试夹具用于为每个测试建立环境,为测试提供所需的一切而不多余其他内容。
🌐 Simply add JUnit annotation @UsePlaywright to your test classes to enable Playwright fixtures. Test fixtures are used to establish environment for each test, giving the test everything it needs and nothing else.
@UsePlaywright
public class TestExample {
@Test
void basicTest(Page page) {
page.navigate("https://playwright.nodejs.cn/");
assertThat(page).hasTitle(Pattern.compile("Playwright"));
}
}
Page page 参数告诉 JUnit 设置 page 夹具并将其提供给你的测试方法。
🌐 The Page page argument tells JUnit to setup the page fixture and provide it to your test method.
以下是预定义 Fixture 的列表:
🌐 Here is a list of the pre-defined fixtures:
| 夹具 | 类型 | 描述 |
|---|---|---|
| 页面 | Page | 此测试运行的独立页面。 |
| 浏览器上下文 | BrowserContext | 此测试运行的独立上下文。page 夹具也属于此上下文。 |
| 浏览器 | Browser | 浏览器在测试之间共享以优化资源。 |
| Playwright | Playwright | Playwright 实例在同一进程上运行的测试之间共享。 |
| 请求 | APIRequestContext | 此测试运行的独立 APIRequestContext。了解如何进行 API 测试。 |
自定义选项
🌐 Customizing options
要自定义夹具选项,你应实现一个 OptionsFactory 并在 @UsePlaywright() 注解中指定该类。
🌐 To customize fixture options, you should implement an OptionsFactory and specify the class in the @UsePlaywright() annotation.
你可以轻松地覆盖 BrowserType.launch() 的启动选项,或 Browser.newContext() 和 APIRequest.newContext() 的上下文选项。请参见以下示例:
🌐 You can easily override launch options for BrowserType.launch(), or context options for Browser.newContext() and APIRequest.newContext(). See the following example:
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.nodejs.cn"));
}
}
@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"));
}
}
并行运行测试
🌐 Running Tests in Parallel
默认情况下,JUnit 会在单进程上顺序运行所有测试。从 JUnit 5.3 开始,你可以更改此行为以并行运行测试,从而加快执行速度(参见 此页面)。由于在没有额外同步的情况下从多个进程使用相同的 Playwright 对象是不安全的,我们建议你为每个进程创建 Playwright 实例,并仅在该进程上使用它。下面是如何并行运行多个测试类的示例。
🌐 By default JUnit will run all tests sequentially on a single thread. Since JUnit 5.3 you can change this behavior to run tests in parallel to speed up execution (see this page). Since it is not safe to use same Playwright objects from multiple threads without extra synchronization we recommend you create Playwright instance per thread and use it on that thread exclusively. Here is an example how to run multiple test classes in parallel.
@UsePlaywright
class Test1 {
@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");
}
}
@UsePlaywright
class Test2 {
@Test
void shouldReturnInnerHTML(Page page) {
page.setContent("<div>hello</div>");
assertEquals("hello", page.innerHTML("css=div"));
}
@Test
void shouldClickButton(Page page) {
Page popup = page.waitForPopup(() -> {
page.evaluate("window.open('about:blank');");
});
assertEquals("about:blank", popup.url());
}
}
配置 JUnit 在每个类中顺序运行测试,并在并行进程上运行多个类(最大进程数等于 CPU 核心数的一半):
🌐 Configure JUnit to run tests in each class sequentially and run multiple classes on parallel threads (with max number of thread equal to 1/2 of the number of CPU cores):
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