Генерація синтетичних тестових даних: підходи та реалізація

Тестові середовища збираються тижнями, а дані з робочого контуру не можна передавати в розробку. Ми налаштовуємо генерацію синтетичних тестових даних під ключ: відтворювані набори під кожен сценарій, без ручної підготовки та ризиків витоку. Час збирання середовищ скорочується в рази.
Часті запитання

Що ламається без синтетичних тестових даних

Тестовий контур зазвичай наповнюють вивантаженням із продуктивної бази — зрізом на пару тисяч записів, знятим давно і з того часу не зміненим.

Перевірки на ньому зелені, а в проді падає сценарій, якого у зрізі не було: замовлення з двома валютами, скасування після часткового повернення, злиття двох акаунтів.

Дефіцит тестових наборів найсильніше б'є по рідкісних станах.

Їхня частка в реальних даних — частки відсотка, у вибірку вони не потрапляють, і нестабільні перевірки роками не бачать ні гонки під час паралельного списання, ні розбіжності часових поясів, ні половини гілок обробки відмов зовнішнього сервісу.

Окрема проблема — реальні дані в тестах. Копії продуктивних таблиць вирушають у тестові контури разом із персональними даними, доступами й історією платежів, а коло людей із доступом там ширше, ніж у проді. Такі копії не можна віддати підряднику і важко відтворити локально.

Маскування поверх копії допомагає частково: зв'язки між таблицями рвуться, довідники та зовнішні ключі перестають збігатися. Тест або падає з причини, не пов'язаної з кодом, або проходить на неузгоджених даних — і обидві ситуації підривають довіру до прогону.

У підсумку перевірки підтверджують не те, що система працює, а те, що вона працює на одному вузькому зрізі.

Розбираємо, як це закривається синтетичними тестовими даними: генерацією наборів із заданими властивостями, контрольованою рідкісністю станів і відтворюваністю від прогону до прогону.

Що дає генерація: вимірювані ефекти

Підготовка середовищ перестає бути очікуванням. Раніше тестове середовище збиралося з копії продуктивної бази: вивантаження, затирання персональних полів, ручне виправлення цілісності посилань — і все заново після кожної зміни схеми.

Генератор будує набір за описом схеми та правилами зв'язків, тому складання скорочується з днів до десятків хвилин і повторюється під час міграції без ручних кроків.

Рідкісні сценарії перестають бути рідкісними. У продуктивних даних скасування на середині процесу, нульові та від'ємні значення, дублі, граничні довжини полів трапляються в десятих частках відсотка — перевірки на них пишуть майже наосліп.

Задаючи частки прямо в правилах, ми отримуємо набір, де на такі поєднання припадає помітна частина записів, і дефект ловиться до релізу, а не в першого клієнта.

Набір відтворюваний. Правила й фіксоване зерно генератора дають однаковий результат на будь-якій машині та в будь-якій гілці: знайдена помилка повторюється в будь-якого інженера без пересилання вивантажень.

Регресійне порівняння двох прогонів показує, що змінилося в коді, а не в даних, — результат перевірки перестає залежати від того, хто і коли оновив тестову базу.

Витік даних зникає як клас інцидентів. Копія продуктивної бази в тестовому контурі або на машині підрядника — найчастіший шлях назовні, і він же найнепомітніший: доступ формально є, подію ніхто не розслідує.

Синтетичний набір не містить персональних даних за побудовою, тому перевіряти на ньому можна без додаткових погоджень, а маскування залишається тільки там, де контур ще працює на копіях.

Порівняння підходів до синтетичних даних

Підхід обирають не за «якістю» даних як такою, а за властивостями, які потрібні тестам: відтворюваність конкретного кейса, покриття рідкісних поєднань, відповідність схемі та цілісність посилань. Нижче — три варіанти, між якими обирають на практиці.

Різниця проявляється на обсязі: правила перестають тримати кореляції між полями, а генеративна модель відходить від реального розподілу.

Тому дивимося не на вибірковий фрагмент, а на поведінку підходу на повному обсязі стенда — найпростіший шар правил на Faker дає відтворюваність, але не спільні розподіли.

Варіант Коли підходить Обмеження
Шаблони та правила Масові валідні за схемою записи: навантажувальні прогони, перевірка міграцій, наповнення стендів Поля генеруються незалежно, кореляції між ними прописуються вручну; рідкісні поєднання майже не трапляються
Генеративні моделі Реалістичні розподіли та аномалії: навчання моделей, тести на рідкісних сценаріях Потрібна репрезентативна вибірка; ризик перенесення персональних даних; результат нестабільний, окремий кейс важко відтворити
Комбінований підхід І масштаб, і реалізм: правила тримають каркас, ключі та зв'язки, модель додає варіативність Потрібен контракт між шарами й валідація кожного кроку, інакше збій одного шару маскується іншим

Комбінація виграє частіше, бо розділяє відповідальність: правила відповідають за цілісність посилань і відтворюваність сценарію, модель — за правдоподібність і рідкісні випадки.

Приймання однакове для всіх варіантів: прогін синтетики через ті самі перевірки схеми та інваріантів, що й продуктивних даних, — набір, який їх не пройшов, у тести не йде.

Як будується генерація: етапи інженерної роботи

Роботи йдуть ітераціями: спочатку знімаємо фактичну картину даних, потім будуємо генератор, потім доводимо, що набори придатні для перевірок.

Зворотний порядок дає правдоподібні, але марні дані — у них не відтворюються зв'язки між сутностями та рідкісні поєднання, на яких найчастіше падає продуктивний контур.

Етапи впровадження

  1. Інвентаризація джерел. Фіксуємо системи, формати вивантажень, обсяги, місця зберігання персональних даних і правила їхнього знеособлення.
  2. Профілювання даних і зв'язків. Рахуємо розподіли, кардинальність полів, частки пропусків, кореляції та правила цілісності посилань — без цього генератор штампує «замовлення без клієнтів».
  3. Налаштування правил генерації. Задаємо типи й діапазони, довідники, бізнес-інваріанти на кшталт збіжності підсумків, окремі сценарії рідкісних і граничних поєднань.
  4. Складання генератора. Налаштовуємо режими: знімок структури, набір у потрібному обсязі, відтворюваність за фіксованим зерном — перевірку, що впала, розбираємо на тому самому наборі.
  5. Приймання наборів. Звіряємо метрики з вихідними й проганяємо перевірки: вони мають падати на підкладених дефектах і не спрацьовувати на чистих даних.
  6. Передача регламенту оновлення. Описуємо, як змінювати правила під час зміни схеми, де лежать конфігурації та як версіонуються набори.

Такий порядок робить генерацію повторюваною: правка схеми джерела не ламає перевірки непомітно.

Що передаємо на руки: артефакти та регламенти

Набори даних без супровідної документації живуть рівно до першої зміни схеми: автор іде, і ніхто не може пояснити, звідки взялося значення в спірному полі. Тому разом із самими даними передаємо все, що потрібно для їхнього відтворення та розвитку без нас.

  • Конфігурації генерації: правила розподілів, обмеження за полями, довідники значень і початкові параметри, за яких набір збирається один в один.
  • Схема зв'язків таблиць: карта зовнішніх ключів і порядок генерації, за якого дочірні записи отримують узгоджені батьківські.
  • Правила доступу: яким командам і сервісам дозволено читати набори, хто має право запускати генерацію та змінювати її параметри.
  • Документація щодо наборів: склад сутностей, обсяг, розподіл ключових полів і перелік сценаріїв, які набір покриває.
  • Регламент оновлення та повторного запуску: що стає приводом для перезбирання, які перевірки проганяються і за яким критерієм набір приймається в роботу.
  • Скрипти контролю цілісності: перевірка посилань, дублів і виходу значень за допустимі межі — виконуються до видачі даних командам.
  • Звіт про покриття: які гілки логіки та класи відмов закриті згенерованими сценаріями, а які свідомо залишені на реальних даних.

Через кілька тижнів після здачі перезбирання під нову схему ви запускаєте самі — без повернення до нас за кожною зміною.

Кейс: скоротили ручну підготовку середовищ

Замовник готував тестові набори вручну: вивантаження з продуктивної бази, чищення персональних даних, дописування відсутніх зв'язків.

На один набір ішло близько п'яти днів, а сценарії збоїв — часткові записи, дублі, обриви транзакцій — не покривалися взагалі, бо таких даних у базі просто не траплялося.

Ми побудували генератор, який читає схему PostgreSQL і збирає узгоджений набір: зовнішні ключі, обмеження та порядок вставлення відтворюються так само, як у реальній базі.

Персональні значення замінюються правдоподібними, а початковий стан генератора фіксується в конфігурації — той самий набір відтворюється під час повторного запуску.

Керованість виявилася важливішою за обсяг: профіль генерації описується декларативно — частки аномалій, розподіли за категоріями, рідкісні стани. Новий сценарій додається правкою профілю, а не переписуванням генератора, і набір збирається під конкретну перевірку.

Що змінилося

Складання набору займає хвилини замість п'яти днів, частка покритих граничних сценаріїв зросла з 40% до 95%, ручні правки даних пішли з процесу випуску. Інженери більше не чекають середовища: чиста база піднімається однією командою.

Окремий ефект — відтворюваність дефектів. Падіння на синтетичному наборі повторюється в будь-якого інженера з тими самими параметрами, тому причина знаходиться за години, а не дні пошуків «а в мене не відтворюється».

Що робити, якщо знеособлення вже впроваджено

Якщо знеособлення вже впроваджено, переробляти його не потрібно — це не альтернатива генерації, а інший інструмент.

Маскування зберігає структуру та зв'язки між полями: значення замінені за словниками, але той самий клієнт, як і раніше, пов'язаний зі своїми замовленнями та історією. Тому копія добре підходить для налагодження й регресії та погано — для перевірки поведінки на рідкісних класах.

Маскування згортає розподіл. Рідкісний код, одиничне поєднання умов, аномальний порядок подій після заміни втрачають частоту або виглядають як звичайні.

Детермінована заміна не дає розмножити такі випадки: у копії їх рівно стільки, скільки було в джерелі, і наростити вибірку вже не можна — набір зафіксовано.

Практичний крок — вбудувати генерацію поруч, використовуючи узгоджену схему знеособлення як специфікацію.

Словники замін, правила зв'язності та допустимі діапазони полів стають вхідними правилами генератора синтетичних тестових даних: він успадковує структуру копії, але не обмежений її обсягом і видає потрібну кількість прогонів, включно з рідкісними поєднаннями.

Міграція йде поступово. Спочатку генерація закриває те, чого копія не дає: обсяг для навантажувальних прогонів, граничні випадки, рідкісні класи. Еталонні набори для регресії залишаються на знеособлених даних, і процес не ламається — змінюється лише джерело частини наборів.

Контроль обов'язковий: звіряємо профілі розподілів і правила цілісності посилань між знеособленим і згенерованим наборами, щоб не з'являлися неможливі комбінації.

Розмежування просте: знеособлення відповідає на питання «чи не витекли дані», генерація — на питання «чи вистачає даних і чи покриті рідкісні класи».

Технічні сумніви: витоки та відтворюваність

Інженери ставлять ті самі питання до старту: чи не потрапить у набір реальне вивантаження, чим підтверджується його якість і що буде, коли схема зміниться. Нижче — відповіді без загальних слів.

Реальні дані можуть потрапити в синтетику?

Генератор працює на описі схеми, розподілів і правил зв'язності, а не на вивантаженні з продуктивного контуру. Реальний зріз беремо лише для звірки розподілів — знеособленим і на етапі аналізу, у готовий набір він не потрапляє.

Як переконатися, що набір якісний?

Набір проганяємо через ті самі перевірки, що й робочі дані: обмеження схеми, унікальність ключів, цілісність посилань, частки категорій за зрізами. Окремо звіряємо розподіли з еталоном, щоб нові записи не зміщували їх непомітно.

Набір відтворюваний на іншій машині?

Так: конфігурація з фіксованим зерном генератора дає той самий набір за кожного прогону. Змінюється зерно, правила або схема — це вже інший набір, і в паспорті видно, з чого він зібраний.

Що відбувається після зміни схеми?

Перегенерація йде за правилами: нові поля описуються, застарілі позначаються, готові набори залишаються незмінними. Тести, прив'язані до попереднього набору, продовжують проходити, поки ви не переведете їх на новий.

Набір витримає навантажувальні перевірки?

Обсяг задається окремо від правдоподібності: генератор масштабується до потрібної кількості записів, зберігаючи зв'язки між сутностями. Так поведінка системи перевіряється на обсягах, яких у робочому контурі немає.

Обговоримо задачу та повернемося з оцінкою і планом

Щоб оцінка спиралася на факти, а не на здогадки, достатньо описати задачу у вільній формі: які системи віддають дані, у якому вигляді надходять записи, де проходять межі чутливих полів і за якими метриками ви зрозумієте, що набір годиться для роботи. Чим конкретніші ввідні, тим точніше ми потрапимо в обсяг і строки.

Зі свого боку повертаємо:

  • розбір джерел — які таблиці та зв'язки потрібно покрити, де даних не вистачає для реалістичного розподілу;
  • схему генератора: правила зв'язності записів, розподіл за полями, роботу з рідкісними класами та пограничними випадками;
  • політику поводження з чутливими даними — маскування, заміна на синтетику, перевірка на оборотність;
  • план робіт за етапами з точками звірки результату на кожному;
  • пілотний набір на одній ділянці — щоб якість перевірялася на даних, а не на презентації;
  • критерії приймання: частка перевірок, що проходять, стійкість моделі на синтетиці, збіг розподілів із реальними;
  • склад передачі: конфігурації, схеми зв'язків, регламент перегенерації під час зміни джерела.

Опишіть задачу та поточні обмеження — повернемося з оцінкою і планом робіт, а пілотний набір зберемо на ваших даних, щоб підхід підтвердився до початку основного етапу.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141