← До блогу

Тестування баз даних у 2026 році: що перевіряти, SQL-запити для тестувальника й інструменти

Користувач бачить інтерфейс, але все цінне живе в базі даних: замовлення, платежі, профілі, історія. Кнопка може показати «Збережено», а в таблицю потрапить неправильна сума, дубль чи «сирота» без батьківського запису. Міграція може пройти на тестовому сервері за секунду й заблокувати продакшн-таблицю на пів години. А запит, що летів на ста рядках, ляже на мільйоні.

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

Короткий вибір

Задача Почати з Альтернативи
Переглянути дані й виконати SQL DBeaver DataGrip, pgAdmin (PostgreSQL)
Модульні тести в самій БД pgTAP (PostgreSQL) tSQLt (SQL Server), utPLSQL (Oracle)
Інтеграційні тести зі справжньою БД Testcontainers DbUnit (Java), Neon (гілки бази)
Тестові дані Faker.js Mockaroo
Міграції схеми Flyway Liquibase, Atlas
Перевірка небезпечних змін і рев'ю SQL Squawk (PostgreSQL) Atlas, Bytebase, SQLFluff
Повільні запити explain.dalibo.com pgMustard, pgBadger
Навантаження на БД HammerDB sysbench, Apache JMeter, Grafana k6
Маскування персональних даних Greenmask PostgreSQL Anonymizer
Якість даних у сховищах і ETL dbt Great Expectations, Soda, Datafold
SQL-ін'єкції sqlmap —
Поділитися прикладом у баг-репорті DB Fiddle —

Що саме тестувати

Напрям Що перевіряємо Приклад дефекту
Структура (схема) Таблиці, стовпці, типи, довжини, значення за замовчуванням, індекси Поле прізвища на 20 символів обрізає подвійні прізвища
Цілісність даних Первинні й зовнішні ключі, UNIQUE, NOT NULL, CHECK Видалили клієнта, а його замовлення лишилися «сиротами»
Коректність даних Що дія в застосунку записала саме те, що мала Знижка застосувалася двічі, сума в БД менша, ніж на екрані
Логіка в БД Збережені процедури, функції, тригери, представлення Тригер аудиту не спрацьовує при масовому оновленні
Транзакції й паралельність Атомарність, ізоляція, блокування, взаємоблокування Два одночасні замовлення продали останній товар двічі
Міграції Застосування, відкат, час виконання, сумісність зі старим кодом Міграція заблокувала таблицю замовлень на 20 хвилин
Продуктивність Плани запитів, індекси, поведінка на великих обсягах Сторінка звіту відкривається хвилину через відсутній індекс
Безпека SQL-ін'єкції, права ролей, шифрування, маскування Обліковий запис застосунку має права на DROP TABLE
Резервне копіювання Що бекап створюється і з нього реально відновлюється база Бекапи «були», але відновлення падає на половині
Якість даних Повнота, унікальність, свіжість, узгодженість у сховищі даних Звіт продажів за вчора порожній, бо ETL тихо впав

SQL-перевірки, які варто знати напам'ять

Ці запити знаходять більшість проблем із даними. Назви таблиць умовні, синтаксис стандартний і працює в PostgreSQL та MySQL.

«Сироти»: дочірні записи без батьківського.

SELECT o.id, o.customer_id
FROM orders o
LEFT JOIN customers c ON c.id = o.customer_id
WHERE c.id IS NULL;

Дублікати там, де їх не має бути.

SELECT email, COUNT(*) AS cnt
FROM users
GROUP BY email
HAVING COUNT(*) > 1;

Порожні значення в обов'язкових з точки зору бізнесу полях.

SELECT COUNT(*) AS total,
       SUM(CASE WHEN phone IS NULL OR phone = '' THEN 1 ELSE 0 END) AS no_phone
FROM customers;

Узгодженість сум: заголовок замовлення проти рядків.

SELECT o.id, o.total, SUM(i.price * i.qty) AS items_total
FROM orders o
JOIN order_items i ON i.order_id = o.id
GROUP BY o.id, o.total
HAVING o.total <> SUM(i.price * i.qty);

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

SELECT id, stock FROM products WHERE stock < 0;
SELECT id, created_at FROM orders WHERE created_at > CURRENT_TIMESTAMP;
SELECT DISTINCT status FROM orders;

Що змінила дія в застосунку. Перед тестом запам'ятайте MAX(id) або час, виконайте дію в інтерфейсі й подивіться нові та змінені рядки:

SELECT * FROM orders WHERE id > 15230 ORDER BY id;
SELECT * FROM audit_log WHERE created_at >= '2026-11-04 10:15:00' ORDER BY created_at;

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

Ручне тестування бази даних

Для ручної роботи потрібен зручний клієнт. DBeaver Community безкоштовний і підключається практично до будь-якої СУБД, DataGrip від JetBrains безкоштовний для некомерційного використання й дуже добре розуміє SQL, а pgAdmin — офіційний інструмент для PostgreSQL. Важливо: на спільних середовищах підключайтеся користувачем лише з правами на читання, щоб випадково не змінити чужі дані.

Що варто перевіряти вручну:

Автоматичні тести

Модульні тести всередині БД

Якщо бізнес-логіка живе в збережених процедурах і тригерах, її варто тестувати там же.

Інтеграційні тести зі справжньою базою

Тести застосунку на вбудованій «легкій» базі замість справжньої часто пропускають помилки: інші типи, інша поведінка NULL і сортування, відсутні функції. Краще тестувати на тій самій СУБД і версії, що й на проді.

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

Тестові дані

Для генерації правдоподібних даних підійдуть Faker.js (у коді, з підтримкою української локалі) і Mockaroo (у браузері, з експортом у SQL і CSV). Генеруйте не лише «гарні» дані, а й крайові: довгі рядки, апострофи в прізвищах (О'Коннор, Мар'яна), порожні необов'язкові поля, дуже старі й майбутні дати.

Міграції схеми: найризикованіше місце

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

Чек-лист тестування міграції:

1. Застосуйте міграцію на копії бази з реалістичним обсягом даних (замаскованих), а не на порожній.

2. Заміряйте час виконання й перевірте, чи блокує вона таблиці. Те, що на тестовій базі займає секунду, на проді може тривати годину.

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

4. Перевірте відкат або план відновлення.

5. Після міграції проженіть SQL-перевірки цілісності з розділу вище й тести pgTAP на структуру.

Оновлення версії СУБД — теж міграція. Підтримка MySQL 8.0 завершилася 30 квітня 2026 року, і багато команд зараз переходять на MySQL 8.4 LTS. PostgreSQL 18 вийшов у вересні 2025 року, а підтримку PostgreSQL 13 припинено в листопаді 2025-го. Перед оновленням проженіть повний регрес на новій версії й порівняйте плани ключових запитів: оптимізатор нової версії може обрати інший план.

Продуктивність запитів

Для навантажувального тестування самої СУБД є HammerDB (стандартні навантаження TPROC-C і TPROC-H) і sysbench (швидкі OLTP-тести MySQL і PostgreSQL). Навантаження через застосунок дають Apache JMeter з JDBC-запитами й Grafana k6. Детальніше — у статті «Навантажувальне тестування».

Безпека бази даних

Більше про це — у статті «Тестування безпеки».

Тестові дані без персональних даних

Найпростіший спосіб отримати реалістичну тестову базу — скопіювати продакшн. І найнебезпечніший: тестові середовища захищені гірше, доступ до них мають підрядники, а дані звідти потрапляють у скриншоти, баг-репорти й чати. Обробка персональних даних регулюється Законом України «Про захист персональних даних», а для клієнтів з ЄС — GDPR.

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

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

Якість даних у сховищах і ETL

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

Базовий набір перевірок для будь-якого завантаження: кількість рядків у джерелі й цілі збігається, ключі унікальні, обов'язкові поля заповнені, контрольні суми (наприклад, сума продажів за день) збігаються з джерелом, дані не старші за очікуваний час.

Якщо ви тестуєте саму СУБД

Для команд, що розробляють бази даних чи їхні форки, є спеціалізовані підходи. SQLancer автоматично генерує бази й запити та шукає логічні помилки, коли СУБД повертає неправильний результат; так знайдено сотні дефектів у SQLite, MySQL, PostgreSQL та інших. Для розподілених баз відомий підхід Jepsen: перевірка гарантій узгодженості під мережевими збоями й падіннями вузлів.

Як звітувати про дефекти в даних

Хороший баг-репорт про базу даних містить:

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

План навчання на місяць

Тиждень Що робити
1 SQL-основи: SELECT, WHERE, JOIN, GROUP BY, HAVING. Інтерактивні уроки SQLBolt і вправи SQLZoo, детектив SQL Murder Mystery для закріплення.
2 Встановіть DBeaver і локальний PostgreSQL або MySQL. Створіть навчальну схему магазину, заповніть її даними з Mockaroo і напишіть усі SQL-перевірки з цієї статті.
3 Транзакції й рівні ізоляції: відтворіть у двох сесіях втрачене оновлення й взаємоблокування. Розберіться з EXPLAIN ANALYZE: додайте індекс і порівняйте плани в explain.dalibo.com.
4 Автоматизація: напишіть кілька тестів pgTAP або інтеграційний тест із Testcontainers, додайте міграції Flyway і перевірку Squawk у GitHub Actions.

Більше тренажерів зібрано в підкатегорії Тренажери для тестувальників.

АІ в тестуванні баз даних

АІ-асистенти добре пишуть SQL за описом («знайди замовлення без оплати, створені понад добу тому»), пояснюють чужі запити й плани виконання, пропонують індекси й генерують тестові дані та крайові випадки. Багато клієнтів, зокрема платні редакції DBeaver і DataGrip, мають вбудованих АІ-помічників, які бачать структуру вашої бази.

Але є два правила. Перше: перевіряйте згенерований SQL перед виконанням, особливо UPDATE і DELETE — АІ легко пропустить умову WHERE чи переплутає стовпці. Друге: не вставляйте реальні персональні чи комерційні дані в публічні чат-боти; передавайте схему й замасковані приклади. АІ-інструменти для роботи з даними шукайте в підкатегорії Бази даних.

Про інші види тестування читайте в статтях «Тестування API», «Навантажувальне тестування», «Тестування безпеки» та «Інструменти для автоматизації тестування». Усі інструменти з цієї статті є в підкатегоріях Тестування і Бази даних.

Часті запитання

Чи потрібно тестувальнику знати SQL?

Так. Навіть мануальному тестувальнику SQL потрібен, щоб перевіряти дані після дій в інтерфейсі, готувати тестові дані й точно описувати дефекти. Рівня SELECT, JOIN, GROUP BY для старту достатньо.

Чим тестування БД відрізняється від тестування API?

Тестування API перевіряє, що повертає сервіс. Тестування БД — що насправді збереглося і чи цілі дані. API може відповісти «200 OK», а в базі опинитися неправильний запис.

Чи можна тестувати на копії продакшн-бази?

Лише після маскування персональних і чутливих даних. Реальні дані в тестовому середовищі — поширена причина витоків.

Як тестувати NoSQL-бази, наприклад MongoDB?

Принципи ті самі: коректність даних, валідація схеми документів, індекси й план запиту (explain()), продуктивність на реальному обсязі. Для інтеграційних тестів так само підходить Testcontainers.

Що робити, якщо логіка в збережених процедурах, а тестів немає?

Почніть з найкритичніших процедур (гроші, залишки, права) і напишіть для них модульні тести в tSQLt, pgTAP чи utPLSQL залежно від СУБД.

Не знаєте, з чого почати?

Запитайте Елю: вона підбере інструменти для тестування баз даних під ваш проєкт і рівень.

Дата перевірки фактів: 4 листопада 2026 року. Умови сервісів, ліцензії й терміни підтримки СУБД можуть змінюватися, тож перевіряйте їх на офіційних сайтах.