Утверждения
Введение
Playwright включает тестовые утверждения в виде функции expect. Чтобы проверить утверждение, вызовите expect(value) и выберите сопоставитель, соответствующий ожидаемому результату. Существует множество универсальных сопоставителей, таких как toEqual, toContain, toBeTruthy, с помощью которых можно проверять любые условия.
expect(success).toBeTruthy();
Playwright также включает специализированные для веб-приложений асинхронные сопоставители, которые ожидают выполнения заданного условия. Рассмотрим следующий пример:
await expect(page.getByTestId('status')).toHaveText('Submitted'); Playwright будет повторно проверять элемент с тестовым идентификатором status, пока найденный элемент не будет содержать текст "Submitted". Элемент будет повторно находиться и проверяться снова и снова, пока условие не будет выполнено или не истечёт время ожидания. Это время ожидания можно передать явно или настроить один раз с помощью параметра testConfig.expect в конфигурации тестов.
По умолчанию время ожидания для утверждений составляет 5 секунд. Подробнее о различных интервалах ожидания.
Утверждения с автоматическими повторами
Следующие утверждения будут повторяться, пока не будут выполнены или пока не истечёт время ожидания для утверждений. Учтите, что утверждения с повторами асинхронны, поэтому их необходимо await.
Утверждения без повторов
Эти утверждения позволяют проверять любые условия, но не выполняют автоматические повторы. Большую часть времени веб-страницы отображают данные асинхронно, и использование утверждений без повторов может привести к нестабильным тестам.
По возможности отдавайте предпочтение утверждениям с автоматическими повторами. Для более сложных утверждений, требующих повторных проверок, используйте expect.poll или expect.toPass.
| Утверждение | Описание |
|---|---|
| expect(value).toBe() | Значения совпадают |
| expect(value).toBeCloseTo() | Числа приблизительно равны |
| expect(value).toBeDefined() | Значение не равно undefined
|
| expect(value).toBeFalsy() | Значение ложно, например false, 0, null и т. д. |
| expect(value).toBeGreaterThan() | Число больше указанного |
| expect(value).toBeGreaterThanOrEqual() | Число больше или равно указанному |
| expect(value).toBeInstanceOf() | Объект является экземпляром класса |
| expect(value).toBeLessThan() | Число меньше указанного |
| expect(value).toBeLessThanOrEqual() | Число меньше или равно указанному |
| expect(value).toBeNaN() | Значение равно NaN
|
| expect(value).toBeNull() | Значение равно null
|
| expect(value).toBeTruthy() | Значение истинно, то есть не равно false, 0, null и т. д. |
| expect(value).toBeUndefined() | Значение равно undefined
|
| expect(value).toContain() | Строка содержит подстроку |
| expect(value).toContain() | Массив или множество содержит элемент |
| expect(value).toContainEqual() | Массив или множество содержит похожий элемент |
| expect(value).toEqual() | Значения похожи: глубокое сравнение и сопоставление с шаблоном |
| expect(value).toHaveLength() | У массива или строки есть длина |
| expect(value).toHaveProperty() | У объекта есть свойство |
| expect(value).toMatch() | Строка соответствует регулярному выражению |
| expect(value).toMatchObject() | Объект содержит указанные свойства |
| expect(value).toStrictEqual() | Значения похожи, включая типы свойств |
| expect(value).toThrow() | Функция выбрасывает ошибку |
Асимметричные сопоставители
Эти выражения можно вкладывать в другие утверждения, чтобы выполнять менее строгую проверку заданного условия.
| Сопоставитель | Описание |
|---|---|
| expect.any() | Соответствует любому экземпляру класса или примитивному значению |
| expect.anything() | Соответствует чему угодно |
| expect.arrayContaining() | Массив содержит определённые элементы |
| expect.arrayOf() | Массив содержит элементы определённого типа |
| expect.closeTo() | Числа приблизительно равны |
| expect.objectContaining() | Объект содержит определённые свойства |
| expect.stringContaining() | Строка содержит подстроку |
| expect.stringMatching() | Строка соответствует регулярному выражению |
Отрицание сопоставителей
В общем случае можно проверить, что верно обратное, добавив .not перед сопоставителем:
expect(value).not.toEqual(0);
await expect(locator).not.toContainText('some text'); Мягкие утверждения
По умолчанию невыполненное утверждение прерывает выполнение теста. Playwright также поддерживает мягкие утверждения: невыполненные мягкие утверждения не прерывают выполнение теста, но помечают его как проваленный.
// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
await expect.soft(page.getByTestId('eta')).toHaveText('1 day');
// ... and continue the test to check more things.
await page.getByRole('link', { name: 'next page' }).click();
await expect.soft(page.getByRole('heading', { name: 'Make another order' })).toBeVisible(); В любой момент выполнения теста можно проверить, были ли ошибки мягких утверждений:
// Make a few checks that will not stop the test when failed...
await expect.soft(page.getByTestId('status')).toHaveText('Success');
await expect.soft(page.getByTestId('eta')).toHaveText('1 day');
// Avoid running further if there were soft assertion failures.
expect(test.info().errors).toHaveLength(0); Учтите, что мягкие утверждения работают только с тестовым runner Playwright.
Пользовательское сообщение expect
В качестве второго аргумента функции expect можно указать пользовательское сообщение, например:
await expect(page.getByText('Name'), 'should be logged in').toBeVisible(); Это сообщение будет отображаться в отчётах как для успешных, так и для неуспешных проверок expect, предоставляя дополнительный контекст об утверждении.
При успешной проверке expect может отображаться такой успешный шаг:
✅ should be logged in @example.spec.ts:18
При неуспешной проверке expect ошибка будет выглядеть так:
Error: should be logged in
Call log:
- expect.toBeVisible with timeout 5000ms
- waiting for "getByText('Name')"
2 |
3 | test('example test', async({ page }) => {
> 4 | await expect(page.getByText('Name'), 'should be logged in').toBeVisible();
| ^
5 | });
6 | Мягкие утверждения также поддерживают пользовательские сообщения:
expect.soft(value, 'my soft assertion').toBe(56);
expect.configure
Можно создать собственный предварительно настроенный экземпляр expect со значениями по умолчанию, такими как timeout и soft.
const slowExpect = expect.configure({ timeout: 10000 });
await slowExpect(locator).toHaveText('Submit');
// Always do soft assertions.
const softExpect = expect.configure({ soft: true });
await softExpect(locator).toHaveText('Submit'); expect.poll
С помощью expect.poll можно преобразовать любое синхронное expect в асинхронную проверку с повторными опросами.
Следующий метод будет повторно вызывать указанную функцию, пока она не вернёт HTTP-статус 200:
await expect.poll(async () => {
const response = await page.request.get('https://api.example.com');
return response.status();
}, {
// Custom expect message for reporting, optional.
message: 'make sure API eventually succeeds',
// Poll for 10 seconds; defaults to 5 seconds. Pass 0 to disable timeout.
timeout: 10000,
}).toBe(200); Также можно задать пользовательские интервалы опроса:
await expect.poll(async () => {
const response = await page.request.get('https://api.example.com');
return response.status();
}, {
// Probe, wait 1s, probe, wait 2s, probe, wait 10s, probe, wait 10s, probe
// ... Defaults to [100, 250, 500, 1000].
intervals: [1_000, 2_000, 10_000],
timeout: 60_000
}).toBe(200); Можно сочетать expect.soft с expect.poll, чтобы выполнять мягкие утверждения в логике опроса. Это позволяет тесту продолжить выполнение, даже если утверждение внутри опроса не пройдёт проверку.
await expect.soft.poll(async () => {
const response = await page.request.get('https://api.example.com');
return response.status();
}).toBe(200); expect.configure({ soft: true }) также поддерживает цепочки вызовов с expect.poll и полезен, когда нужно повторно использовать настроенный экземпляр.
const softExpect = expect.configure({ soft: true });
await softExpect.poll(async () => {
const response = await page.request.get('https://api.example.com');
return response.status();
}).toBe(200); expect.toPass
Можно повторять блоки кода, пока они не будут выполнены успешно.
await expect(async () => {
const response = await page.request.get('https://api.example.com');
expect(response.status()).toBe(200);
}).toPass(); Также можно задать пользовательские интервалы ожидания и повтора:
await expect(async () => {
const response = await page.request.get('https://api.example.com');
expect(response.status()).toBe(200);
}).toPass({
// Probe, wait 1s, probe, wait 2s, probe, wait 10s, probe, wait 10s, probe
// ... Defaults to [100, 250, 500, 1000].
intervals: [1_000, 2_000, 10_000],
timeout: 60_000
}); Учтите, что по умолчанию toPass имеет время ожидания 0 и не учитывает пользовательское время ожидания expect.
Добавление пользовательских сопоставителей с помощью expect.extend
Можно расширить утверждения Playwright, добавив пользовательские сопоставители. Эти сопоставители будут доступны в объекте expect.
В этом примере мы добавим пользовательскую функцию toHaveAmount. Пользовательский сопоставитель должен возвращать флаг pass, указывающий, прошло ли утверждение проверку, и обратный вызов message, который используется при невыполнении утверждения.
import { expect as baseExpect } from '@playwright/test';
import type { Locator } from '@playwright/test';
export { test } from '@playwright/test';
export const expect = baseExpect.extend({
async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
const assertionName = 'toHaveAmount';
let pass: boolean;
let matcherResult: any;
try {
const expectation = this.isNot ? baseExpect(locator).not : baseExpect(locator);
await expectation.toHaveAttribute('data-amount', String(expected), options);
pass = true;
} catch (e: any) {
matcherResult = e.matcherResult;
pass = false;
}
if (this.isNot) {
pass =!pass;
}
const message = pass
? () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
'\n\n' +
`Locator: ${locator}\n` +
`Expected: not ${this.utils.printExpected(expected)}\n` +
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
: () => this.utils.matcherHint(assertionName, undefined, undefined, { isNot: this.isNot }) +
'\n\n' +
`Locator: ${locator}\n` +
`Expected: ${this.utils.printExpected(expected)}\n` +
(matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');
return {
message,
pass,
name: assertionName,
expected,
actual: matcherResult?.actual,
};
},
}); Теперь в тесте можно использовать toHaveAmount.
import { test, expect } from './fixtures';
test('amount', async () => {
await expect(page.locator('.cart')).toHaveAmount(4);
}); Совместимость с библиотекой expect
примечаниеНе путайте
expectPlaywright с библиотекойexpect. Последняя не полностью интегрирована с тестовым runner Playwright, поэтому используйте собственныйexpectPlaywright.
Объединение пользовательских сопоставителей из нескольких модулей
Можно объединить пользовательские сопоставители из нескольких файлов или модулей.
import { mergeTests, mergeExpects } from '@playwright/test';
import { test as dbTest, expect as dbExpect } from 'database-test-utils';
import { test as a11yTest, expect as a11yExpect } from 'a11y-test-utils';
export const expect = mergeExpects(dbExpect, a11yExpect);
export const test = mergeTests(dbTest, a11yTest); import { test, expect } from './fixtures';
test('passes', async ({ database }) => {
await expect(database).toHaveDatabaseUser('admin');
});
© 2026 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/test-assertions