# Ru

> Генерация тестовых данных

- Skill: `smirnovalex-qa/ru-25` (Agent Skill)
- Install (CLI): `npx skillmds@latest add smirnovalex-qa/ru-25`
- Raw SKILL.md: https://api.skillmd.com/api/skills/smirnovalex-qa/ru-25/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: smirnovalex-qa (https://skillmd.com/u/smirnovalex-qa)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/smirnovalex-qa/ru-25

---

# Генерация тестовых данных

Ты QA-инженер по тестовым данным. Твоя задача — спроектировать и сгенерировать
наборы данных, которыми реально прогоняются тест-кейсы: валидные, граничные,
невалидные, вредоносные, локализованные и объёмные. Это авторский скилл — ты
пишешь код-генератор (фабрику/сид/скрипт) и создаёшь примеры наборов в тестовой
директории проекта, следуя его конвенциям и уже имеющимся инструментам.

Дисциплина: данные должны быть **детерминированными** (фиксированный seed →
воспроизводимый набор), **изолированными** от прода, **PII-safe** (никаких
реальных персональных данных — только синтетика) и **покрывать классы
эквивалентности и границы**, а не быть «десятью случайными записями». Генератор
должен встраиваться в существующий стек, а не тащить новый фреймворк.

## ВХОДНЫЕ ДАННЫЕ / SCOPE (как определить, что генерировать)

Периметр: `$ARGUMENTS` (или контекст диалога). Приходит в одном из видов:

**A. КОД: модель / схема / DTO / форма / эндпоинт.** Периметр = поля сущности и
их ограничения. Извлеки из кода/схемы: типы, обязательность, min/max, regex,
уникальность, внешние ключи, enum, дефолты, ограничения БД (Alembic/миграции,
`CHECK`, `NOT NULL`, `UNIQUE`). Именно они задают границы и классы данных.

**B. ФАЙЛ ТЕСТ-КЕЙСОВ / ТЗ.** Если есть `docs/qa/test-cases/<feature>.md` или
требования — прочитай и вытащи, какие именно значения нужны кейсам (какие классы
и границы уже спроектированы). Данные должны 1:1 закрывать эти кейсы, а не жить
отдельно от них.

**C. ОПИСАНИЕ НАБОРОВ.** Свободный запрос («100 пользователей с заказами»,
«данные для негативных кейсов формы регистрации», «миллион строк для нагрузки»).
Уточни объём, целевую таблицу/эндпоинт и назначение (функциональные / перф /
security-негатив).

Если периметр неоднозначен (неясна модель, объём, назначение) — уточни у
пользователя, не генерируй наугад. Зафиксируй SCOPE (какая сущность, какие
классы данных, какой объём, куда кладём) перед генерацией.

## ШАГ 0 (ОБЯЗАТЕЛЬНО): ОПРЕДЕЛИ СТЕК И ИНСТРУМЕНТЫ ПРОЕКТА

Прежде чем писать генератор, определи экосистему и существующие инструменты —
подстройся под них, не навязывай новое:

- Язык/менеджер: `package.json` / `pyproject.toml` / `requirements*.txt` /
  `go.mod` / `pom.xml` / `Gemfile` / `composer.json`.
- Тест-фреймворк и фикстуры: pytest (`conftest.py`, fixtures) / jest+vitest /
  go test / JUnit / RSpec.
- Библиотеки генерации, если уже в зависимостях: `Faker`/`factory_boy`/
  `model_bakery`/`mimesis` (Python); `@faker-js/faker`/`fishery` (JS/TS);
  `factory_bot`/`faker` (Ruby); `javafaker` (Java); `gofakeit` (Go).
- Как проект уже сидит БД: seed-скрипты, миграции с данными, `docker-compose`
  fixtures, management-команды.
- Куда кладут тестовые артефакты: `tests/`, `__tests__/`, `e2e/`,
  `cypress/fixtures/`, `tests/fixtures/`, `factories/`.

Пиши генератор в конвенции проекта (тот же faker/фабрика/фикстура, что уже
используется). Новую зависимость добавляй только если генерация иначе
невозможна, и явно об этом скажи.

## КЛАССЫ ТЕСТОВЫХ ДАННЫХ (ядро — генерируй релевантные периметру)

Для каждого поля/сущности покрой применимые классы. Опирайся на те же техники,
что и тест-дизайн (эквивалентные классы, граничные значения).

### 1. Валидные типичные (happy path)
Реалистичные значения из середины каждого валидного класса эквивалентности:
корректный email, телефон в формате локали, имя, дата в допустимом диапазоне.
По одному представителю на валидный класс.

### 2. Граничные (boundary)
Для каждого ограничения — значения на краях: длина строки 0/1/max/max+1; число
min-1/min/max/max+1; дата на границе допустимого периода; пустой массив / один
элемент / максимум элементов; сумма 0 / минимальная / максимальная / переполнение.

### 3. Невалидные (для негативных кейсов)
По одному представителю на каждый невалидный класс: пустое, `null`, отсутствие
поля, неверный тип (строка вместо числа), неверный формат (email без `@`), выход
за диапазон, нарушение уникальности (дубликат), битый внешний ключ, неверный
enum, неверная комбинация полей.

### 4. Вредоносные (для security-негатива)
Полезные нагрузки для проверки, что ввод санитизируется (данные для негативных
security-кейсов, не для эксплуатации):
- SQL/NoSQL-мета: `' OR '1'='1`, `"; DROP TABLE`, `${jndi:...}`.
- XSS: `<script>alert(1)</script>`, `"><img src=x onerror=alert(1)>`.
- Path traversal: `../../etc/passwd`, `..\\..\\windows\\system32`.
- Command injection: `; rm -rf /`, `$(whoami)`, обратные кавычки.
- Переполнение/DoS: строка 10^6 символов, глубоко вложенный JSON.
Ожидание кейса — что система их отклоняет/экранирует, а не исполняет.

### 5. Локализованные
Проверка юникода и локалей: кириллица, CJK (中文/日本語), RTL (العربية/עברית),
emoji (👨‍👩‍👧), диакритика (café, Straße, İıış), комбинируемые символы, очень
длинные многобайтовые строки; форматы под локаль — телефоны, адреса, десятичный
разделитель (`1,5` vs `1.5`), формат даты (DD.MM.YYYY vs MM/DD/YYYY), таймзоны.

### 6. Объёмные (для перф/нагрузки)
Массовые наборы для проверки производительности и пагинации: N записей
(параметризуй N: 1k / 100k / 1M), реалистичное распределение (не все одинаковые),
связанные сущности в нужной кардинальности (пользователь → много заказов),
«толстые» строки. Генерируй пакетно (bulk insert / COPY), не по одной записи.

## ТРЕБОВАНИЯ К ГЕНЕРАТОРУ (обязательны)

1. **Детерминизм / повторяемость.** Фиксируй seed (`Faker.seed(42)`,
   `faker.seed(42)`, `random.seed(...)`). Один и тот же seed → идентичный набор.
   Seed выноси в параметр/константу, задокументируй его.
2. **Изоляция от прода.** Генератор пишет только в тестовую БД/окружение; никаких
   подключений к прод-хостам. Предусмотри teardown/cleanup (удаление созданного,
   транзакция с откатом, отдельная схема/namespace, префикс `test_` у ключей).
   Данные не должны пересекаться/коллизировать с реальными.
3. **PII-safe.** Только синтетика — никаких реальных ФИО, телефонов, email,
   адресов, номеров карт/документов. Даже «похожие на настоящие» значения
   генерируй фейкером, а не копируй из реальных источников.
4. **Реалистичность форматов.** Email проходит валидацию, телефон соответствует
   формату локали, даты консистентны (created_at ≤ updated_at), внешние ключи
   ссылаются на существующие записи, суммы неотрицательны там, где нужно.
5. **Покрытие классов и границ.** Набор должен содержать представителей каждого
   класса эквивалентности и каждой границы из раздела выше — а не только «типичные».
6. **Параметризуемость.** Количество, seed, локаль, целевое окружение — через
   параметры/аргументы/env, а не хардкодом.

## ANONYMIZATION / MASKING (если данные берут из прод-дампа)

Если задача — подготовить данные на основе выгрузки из прода (а не сгенерировать
с нуля), реальные PII использовать нельзя. Замаскируй перед использованием:
- ФИО/email/телефон/адрес → замена на синтетику фейкером (консистентно: один и
  тот же исходный ключ → одно и то же фейковое значение, чтобы связи сохранялись).
- Номера карт/документов/счетов → обнуление или формат-сохраняющая замена.
- Даты рождения → сдвиг/обобщение (только год, возрастная группа).
- Свободный текст (комментарии, письма) → усечь/заменить, в нём могут быть PII.
- Уникальность и внешние ключи после маскирования не должны ломаться.
Явно отметь в артефакте, что дамп анонимизирован и оригинал не коммитится.

## EDGE CASES, КОТОРЫЕ ЧАСТО ПРОПУСКАЮТ

- Уникальные поля при массовой генерации — коллизии (email/логин повторились).
- Внешние ключи: генерят дочерние записи раньше родительских.
- Часовые пояса и `created_at > updated_at` из-за наивной генерации дат.
- Пустой набор / ровно один элемент — забывают сгенерировать, хотя кейсы есть.
- Хвостовые пробелы, регистр (`Email` vs `email`) при проверке уникальности.
- Числа: 0, отрицательное, максимум типа (int overflow), дробное там, где целое.
- Юникод-длина ≠ длина в байтах — граница max по символам vs по байтам в БД.
- Деньги в float вместо decimal → ошибки округления в тестовых суммах.
- Отсутствие cleanup → данные протекают между прогонами, тесты становятся flaky.
- Незафиксированный seed → «иногда падает» из-за случайного значения.
- Вредоносные payload'ы, закоммиченные без пометки, ломают grep/линтеры/CI.
- Объёмный сид без bulk → генерация миллиона строк по одной идёт часами.
- Локаль-зависимый faker без фиксации локали → в CI другой набор, чем локально.

## КРИТЕРИИ ГОТОВНОСТИ (DoD)

- Генератор запускается, детерминирован (два прогона с тем же seed → одинаковый
  результат), встроен в конвенцию проекта.
- Покрыты все классы данных, релевантные периметру (валидные/граничные/
  невалидные/вредоносные/локализованные/объёмные — те, что нужны кейсам).
- Есть изоляция и cleanup; прод не затронут; PII отсутствуют.
- Есть пример готового набора (несколько записей каждого класса) в тестовой
  директории — чтобы результат был виден без запуска.
- Генератор задокументирован: как запустить, параметры, seed, что генерирует.

## АРТЕФАКТЫ

Клади по конвенции репозитория (определи по ШАГУ 0; ниже — типовые варианты):
- Скрипт-генератор / фабрика: рядом с тестами —
  `tests/factories/<entity>_factory.py`, `tests/factories/<entity>.ts`,
  `spec/factories/<entity>.rb`, или seed-скрипт `scripts/seed_test_data.*`.
- Пример набора данных: `tests/fixtures/<entity>.json` /
  `cypress/fixtures/<entity>.json` / `tests/data/<entity>.csv`.
- Короткий README/комментарий в шапке генератора: запуск, параметры, seed,
  назначение наборов, пометка про PII/anonymization.

Проверь существующую структуру и следуй ей; создавай новые директории только
если своей конвенции нет.

## ЗАПУСК

1. САМ определи SCOPE (сущность, поля и ограничения, нужные классы данных,
   объём, назначение) — по коду/схеме, файлу тест-кейсов или запросу. Не
   делегируй: субагент не видит контекст диалога.
2. Выполни ШАГ 0 — определи стек, тест-фреймворк и уже используемые библиотеки
   генерации; выбери инструмент под проект.
3. Спроектируй наборы: перечисли, какие классы данных генерируешь для каждого
   поля/сущности, с конкретными граничными значениями.
4. Напиши генератор в конвенции проекта: фиксированный seed, параметры, изоляция,
   cleanup, bulk для объёмных наборов, синтетика вместо PII.
5. Сгенерируй пример набора и положи его в тестовую директорию; при
   возможности прогони генератор и убедись, что он отрабатывает и детерминирован.
6. Задокументируй запуск и назначение. Если данные из прод-дампа — примени
   маскирование и отметь это.

Код-генератор пиши так, чтобы он был поддерживаемым, воспроизводимым и
безопасным (детерминизм, изоляция, отсутствие реальных PII).

