Перейти к основному содержимому

Тестовые фреймворки

Введение

С помощью нескольких строк кода вы можете подключить Playwright к вашему любимому Java тестовому фреймворку.

Экземпляры Playwright и Browser могут быть повторно использованы между тестами для повышения производительности. Мы рекомендуем запускать каждый тестовый случай в новом BrowserContext, таким образом состояние браузера будет изолировано между тестами.

JUnit

В JUnit вы можете инициализировать Playwright и Browser в методе @BeforeAll и уничтожать их в методе @AfterAll. В примере ниже все три тестовых метода используют один и тот же Browser. Каждый тест использует свой собственный BrowserContext и Page.

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 {
// Общий для всех тестов в этом классе.
static Playwright playwright;
static Browser browser;

// Новый экземпляр для каждого тестового метода.
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 создаст новый экземпляр класса для каждого тестового метода). Храните объекты Playwright и Browser в полях экземпляра. Они будут общими для всех тестов. Каждый экземпляр класса будет использовать свою собственную копию Playwright.

// Подклассы унаследуют поведение PER_CLASS.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestFixtures {
// Общий для всех тестов в классе.
Playwright playwright;
Browser browser;

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

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

// Новый экземпляр для каждого тестового метода.
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 для выполнения тестов в каждом классе последовательно и запуска нескольких классов в параллельных потоках (с максимальным числом потоков, равным 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

Вы можете использовать скрипт конфигурации сборки Gradle, написанный на Groovy или Kotlin.

plugins {
application
id 'java'
}

repositories {
mavenCentral()
}

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

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

// Использование: ./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 вы можете инициализировать Playwright и Browser в методе @BeforeClass и уничтожать их в методе @AfterClass. В примере ниже все три тестовых метода используют один и тот же Browser. Каждый тест использует свой собственный BrowserContext и Page.

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 {
// Общий для всех тестов в этом классе.
Playwright playwright;
Browser browser;

// Новый экземпляр для каждого тестового метода.
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());
}
}