Назад к блогу
Идентичность

Гигиена тестовых данных и состояния браузера в автоматизации

Назначайте владельцев синтетическим данным, состоянию браузера и очистке для каждого изолированного worker.

Документация

Нужна структурированная документация по теме Идентичность?

Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.

Синтетические тестовые данные проходят через принадлежащее worker состояние браузера к очистке

Надёжный тест заранее называет вход, владельца, наблюдаемый результат и границу очистки. Новый контекст не делает общими аккаунт, запись сервера или каталог загрузки независимыми. Используйте синтетические данные из документированного тестового интерфейса, а не персональные документы или реальные учётные данные. См. руководство по fixture и изоляции.

Матрица владельцев

РесурсСоздательВладелец измененийНаблюдениеГраница очистки
Синтетический аккаунттестовый сервисworker сценариязаголовок или доступAPI сброса
Контекст и cookiesfixturefixtureчистый контекстзакрытие в finally
Базовое состояниерепозиторийкопия fixtureзагруженный маршрутхранить baseline; удалить копию
Каталог артефактовworkerworkerкороткая квитанцияудалить локальный путь
Удалённая задачаприложениесервисдокументированный статусотмена или истечение

Закрытие контекста не доказывает удаление записи сервера. Загружайте 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;

Таблица решений

НаблюдениеКатегорияДействиеНе доказано
Нет baselinefixtureостановить тест и исправить входдоступность сервиса
Видны старые 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 из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.