Гигиена тестовых данных и состояния браузера в автоматизации
Назначайте владельцев синтетическим данным, состоянию браузера и очистке для каждого изолированного worker.
Нужна структурированная документация по теме Идентичность?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Надёжный тест заранее называет вход, владельца, наблюдаемый результат и границу очистки. Новый контекст не делает общими аккаунт, запись сервера или каталог загрузки независимыми. Используйте синтетические данные из документированного тестового интерфейса, а не персональные документы или реальные учётные данные. См. руководство по fixture и изоляции.
Матрица владельцев
| Ресурс | Создатель | Владелец изменений | Наблюдение | Граница очистки |
|---|---|---|---|---|
| Синтетический аккаунт | тестовый сервис | worker сценария | заголовок или доступ | API сброса |
| Контекст и cookies | fixture | fixture | чистый контекст | закрытие в finally |
| Базовое состояние | репозиторий | копия fixture | загруженный маршрут | хранить baseline; удалить копию |
| Каталог артефактов | worker | worker | короткая квитанция | удалить локальный путь |
| Удалённая задача | приложение | сервис | документированный статус | отмена или истечение |
Закрытие контекста не доказывает удаление записи сервера. Загружайте baseline только для чтения, а новую копию именуйте worker и попыткой. Разным worker нужны разные синтетические записи либо явно сериализованная мутация.
Сбойная fixture
Страница без маркера готовности проверяет ограниченный сбой и очистку:
import os from 'node:os';
import path from 'node:path';
import { mkdtemp, rm } from 'node:fs/promises';
import { chromium } from 'playwright';
import { expect } from '@playwright/test';
const dir = await mkdtemp(path.join(os.tmpdir(), 'state-hygiene-'));
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({ baseURL: 'http://fixture.test' });
const page = await context.newPage();
await page.route('/fixtures/without-ready-marker', route =>
route.fulfill({ status: 200, contentType: 'text/html', body: '<main><p>Waiting</p></main>' })
);
let failure;
const remember = (label, error) => {
const current = new Error(`${label}: ${error.message}`, { cause: error });
failure = failure ? new AggregateError([failure, current], `${failure.message}; ${label} failed`) : current;
};
try {
await page.goto('/fixtures/without-ready-marker');
await expect(page.getByRole('status')).toHaveText('Ready', { timeout: 250 });
} catch (error) {
remember('проверка fixture', error);
} finally {
try {
await context.close();
} catch (error) {
remember('закрытие контекста', error);
}
try {
await rm(dir, { recursive: true, force: true });
} catch (error) {
remember('очистка артефакта', error);
}
try {
await browser.close();
} catch (error) {
remember('закрытие браузера', error);
}
}
if (failure) throw failure;
Таблица решений
| Наблюдение | Категория | Действие | Не доказано |
|---|---|---|---|
| Нет baseline | fixture | остановить тест и исправить вход | доступность сервиса |
| Видны старые cookies | состояние браузера | выбросить контекст | отзыв серверной сессии |
| Worker перезаписывают запись | тестовые данные | разделить или сериализовать | ошибка BrowserContext |
| Проверка прошла, очистка нет | инфраструктура | сохранить обе ошибки | удаление на сервере |
| Повтор успешен | неопределённый результат | запросить поддерживаемый статус | безопасность первой попытки |
Проверяйте переходы состояния
Рассматривайте состояние как последовательность: baseline, видимая проверка и очистка. Смена аккаунта требует штатного выхода и нового контекста; удаление локального хранилища не отзывает удалённую сессию. Версию baseline нужно сохранять, а неполный файл отклонять, не создавая его молча заново.
Защищайте секреты и артефакты
Снимок состояния может содержать cookies. Ограничьте права, храните короткую квитанцию со сценарием, worker, результатом и очисткой. Не записывайте токены или текст страницы. Временный каталог и хранение CI имеют разных владельцев. См. также руководство по загрузкам и скачиваниям.
Проверяйте повторы и параллельность
Именуйте файлы сценарием, worker и попыткой без личных идентификаторов. После тайм-аута запросите поддерживаемый статус до повтора мутации. После обновления запускайте чистый контекст, просроченное состояние, смену аккаунта, параллельный вывод и принудительную очистку.
Повторяемость дают контролируемые входы, а не общий долгоживущий браузер.
Зафиксируйте маршрут, схему fixture, форму синтетической записи и нужную конфигурацию.
Тогда изменение относится к приложению, fixture или runner.
Не используйте общую настройку, которая создаёт аккаунты, выдаёт разрешения и оставляет страницы открытыми.
Такая настройка смешивает причину первого сбоя с эффектами прежних тестов.
Стартовая fixture сообщает о загрузке известного состояния или завершённом документированном входе.
Она не выводит материал сессии.
Fixture данных сообщает метку сценария и результат сброса.
Она не перебирает записи в поиске случайно подходящей.
Отсутствующий вход означает ошибку fixture.
Незапланированная замена делает результат неповторяемым.
Часть состояния живёт вне браузера: например, в симуляторе почты или уведомлений.
Каждой такой зависимости нужен свой синтетический namespace и чек.
Браузер наблюдает подтверждение, но не доказывает все последующие доставки.
Для сервисных фактов используйте документированный тестовый интерфейс сервиса.
Закрытие страницы освобождает её listeners и handles.
Закрытие контекста освобождает состояние этого контекста.
Эти действия сами не удаляют скопированный файл, загруженный объект или token другого устройства.
Выполняйте штатный выход, пока страница доступна.
Затем закрывайте ресурсы браузера и локальный каталог worker.
Сбой очистки приложения может не зависеть от закрытия браузера.
Сохраняйте оба наблюдения в короткой квитанции.
Не ищите похожие профили, каталоги или контексты ради расширенной очистки.
При неудачном удалении процедура восстановления может изолировать только собственный известный каталог.
Синтетическая запись должна быть узнаваемой, но не похожей на персональные данные.
Используйте префикс сценария, метку запуска и значения для нужной проверки.
Для граничного случая меняйте одно объявленное свойство входа.
Сброс возвращает известную baseline, а не угадывает частичное исправление.
Не используйте автоматически метку с незавершённой очисткой.
Проверка описывает то, что видит пользователь или разрешённый тест.
Пустое локальное хранилище не доказывает отзыв удалённой сессии.
Завершённая навигация не доказывает асинхронную задачу.
Записывайте отсутствующий сигнал, неожиданный видимый статус или документированную категорию ошибки.
Перед изменением ожиданий сначала проверьте уникальные запись, контекст и частный каталог.
Регулярная проверка сопоставляет квитанцию сбоя с объявленным контрактом до изменения ожидания.
Возможность и ограничение BotBrowser
BotBrowser предоставляет изолированные BrowserContexts с отдельными cookies, хранилищем и состоянием сессии для разрешённых синтетических сценариев. Это позволяет проверить отсутствие унаследованного клиентского состояния; см. документацию об изоляции аккаунтов. BotBrowser не заменяет управление жизненным циклом Playwright/Selenium, очистку приложения, отзыв серверной сессии или работу с секретами. Он не гарантирует принятие просроченной cookie, отмену задачи или удаление записи провайдера.
Храните только сценарий, worker, видимый результат и статус очистки. Перед изменением fixture выполните чистый контекст, просроченное состояние и этот принудительный сбой.
Источники
Похожие статьи
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.