vyvchy
    Теми розділу

    05 · Бази даних і SQL для QA

    Бази даних у роботі QA

    Зміст

    UI показує «120 активних замовлень», API у відповіді віддає 118, а користувач у чаті клянеться, що бачить 121. Хто з них має рацію — знає лише одне місце: база даних. Усе, що застосунок показує на екрані чи повертає через API, — це вже інтерпретація: щось відфільтрувалося, щось закешувалося, щось порахувалося на льоту. А в базі лежать самі факти, без прикрас. Тому рано чи пізно тестувальник перестає вірити екрану на слово й іде дивитися в першоджерело — і для цього потрібен SQL.

    Ця глава — вступна карта всього розділу. Тут ми не пишемо запитів (це почнеться з наступних глав), а розбираємося з рамкою: що таке база даних і чим вона відрізняється від СУБД, де вона стоїть у клієнт-серверній архітектурі, навіщо QA взагалі туди лізе, чим реляційні бази відрізняються від нереляційних, як під'єднатися клієнтом і — найважливіше для новачка — яке одне правило рятує від катастрофи на проді. Решта розділу нарощує SQL-навички; ця глава дає орієнтацію, щоб було зрозуміло, куди ці навички прикладати.

    База даних, СУБД і де вони в архітектурі

    Спершу розведемо два поняття, які початківці плутають. База даних (database, БД) — це власне організований набір даних: таблиці з замовленнями, користувачами, платежами. Система керування базами даних (database management system, СУБД, DBMS) — це програма, яка ці дані зберігає, віддає й захищає: PostgreSQL, MySQL, Microsoft SQL Server, Oracle. Коли кажуть «у нас Postgres», мають на увазі СУБД; а конкретні дані застосунку — це база (часто й не одна) всередині неї. Різниця не педантична: підключаєшся ти до СУБД, а працюєш — з конкретною базою в ній.

    Тепер про місце в системі. У клієнт-серверній архітектурі (див. главу Клієнт-сервер і як працює веб) сам застосунок даних не зберігає. Коли ти натискаєш кнопку, сервер застосунку виконує бізнес-логіку, а по дані звертається до окремого процесу — СУБД. Спілкуються вони мовою SQL по мережі: застосунок надсилає запит, СУБД повертає рядки. Дуже часто СУБД працює навіть на окремій машині зі своїм мережевим портом — це окремий сервер зі своєю відповідальністю.

    Ключове для QA: до тієї самої СУБД можна під'єднатися напряму своїм клієнтом — в обхід UI й API, одразу до джерела істини. Там видно все як є: без кешу, без форматування, без прав доступу, які ховають частину даних у застосунку.

    HTTP, API

    SQL по мережі

    SQL, тільки читання

    Користувач
    браузер / застосунок

    Сервер застосунку
    бізнес-логіка

    СУБД
    PostgreSQL / MySQL

    Файли даних
    на диску

    QA: SQL-клієнт

    HTTP, API

    SQL по мережі

    SQL, тільки читання

    Користувач
    браузер / застосунок

    Сервер застосунку
    бізнес-логіка

    СУБД
    PostgreSQL / MySQL

    Файли даних
    на диску

    QA: SQL-клієнт

    Одне застереження на майбутнє: «база» рідко буває одна. Часто є основна база (primary) і її копії для читання (репліки), між якими дані доїжджають із затримкою; у мікросервісній архітектурі кожен сервіс може мати власну базу. Через це той самий факт іноді видно в одному місці й ще не видно в іншому — до цього ми повернемося, коли говоритимемо про консистентність.

    SQL для QA — це не про те, щоб писати запити для застосунку (це робота розробника). Це про те, щоб читати й перевіряти. Ось живі сценарії, у яких без бази не обійтися:

    • Звірити правду з інтерфейсом. Дашборд показує суму, звіт — кількість, лист — статус. SQL дає незалежний оракул: порахувати те саме напряму в базі й порівняти. Розбіжність цифри на UI й у базі — класичний баг.
    • Підготувати тестові дані й потрібний стан. Щоб перевірити «що буде із замовленням, якому 400 днів», інколи простіше знайти чи виставити такий запис у базі, ніж клікати сценарій годинами. (Стратегія тестових даних — окрема тема, глава Тестові дані і БД в автотестах.)
    • Розслідувати баг. Користувач зареєструвався, а листа не отримав — запис у таблиці users є, а в email_queue немає? Значить, проблема не в реєстрації, а в черзі листів. База показує, на якому кроці ланцюжок обірвався.
    • Бачити невидиме. Застосунок часто ховає дані: «видалений» запис насправді лишається з міткою deleted_at, фонове завдання має статус, аудит-лог пише історію змін. Через UI цього не побачиш, а в базі — прямо.
    • Підсилити баг-репорт. «Після оплати замовлення лишається в статусі new» звучить переконливіше з рядком із бази, ніж зі скриншотом.

    Від мануального тестувальника сьогодні часто очікують базового SQL, а на співбесідах рівня trainee/junior це — стандартний блок питань. Хороша новина: щоб бути корисним, не треба знати СУБД як адміністратор — достатньо впевнено вибирати й фільтрувати дані.

    Реляційні та нереляційні бази — оглядово

    Реляційні бази зберігають дані в таблицях: рядки (записи) і стовпці (поля), із заздалегідь заданою схемою (schema) — які є колонки й якого типу. Таблиці пов'язані між собою (замовлення посилається на користувача), працюють через SQL і дають сильні гарантії цілісності — про них ітиметься в главі Транзакції та ACID. Це PostgreSQL, MySQL/MariaDB, SQL Server, Oracle. Саме на них тримається більшість бізнес-систем, тому 17 із 18 глав цього розділу — про реляційні бази й SQL.

    Нереляційні (NoSQL) — це парасолька над усім, що влаштоване інакше. Кілька родин:

    Тип NoSQLІдеяПриклад
    ДокументніЗаписи-документи (JSON-подібні), гнучка схемаMongoDB
    Ключ-значенняПроста пара «ключ → значення», дуже швидкоRedis
    КолонковіОптимізовані під величезні обсяги й записCassandra
    ГрафовіВузли й зв'язки між нимиNeo4j

    Головні відмінності від реляційних — гнучка або відсутня схема (можна класти документи різної форми в одну колекцію) і легше горизонтальне масштабування, але за це часто платять слабшими гарантіями узгодженості (eventual consistency — «колись узгодиться»). Для QA це означає інший клас багів: не «порушено зовнішній ключ», а «поле, яке ми чекали, у половині документів просто відсутнє». Оглядово NoSQL розбирає остання глава розділу — NoSQL для QA: MongoDB, Redis і консистентність.

    АспектРеляційна БДNoSQL
    Модель данихТаблиці, рядки, стовпціДокументи / ключ-значення / граф
    СхемаФіксована, задана напередГнучка або відсутня
    МоваSQL (з діалектами)У кожної своя (API, власна мова)
    Зв'язкиЧерез ключі, на рівні БДЧасто на рівні застосунку
    Типова силаЦілісність, складні запитиМасштаб, швидкість, гнучкість

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

    Клієнти й параметри підключення

    Щоб зазирнути в базу, потрібен клієнт — програма, яка вміє під'єднатися до СУБД і виконати запит. Їх два типи. Консольні (CLI): psql для PostgreSQL, mysql для MySQL — швидко, легко в скриптах, але без візуалізації. Графічні (GUI): DBeaver (безкоштовний, універсальний — розуміє десятки СУБД), DataGrip (від JetBrains, платний, потужний), pgAdmin (спеціалізований під PostgreSQL). Для новачка GUI зручніший: дерево таблиць, автодоповнення, результат у вигляді сітки.

    Незалежно від клієнта, щоб під'єднатися, потрібен той самий набір параметрів:

    ПараметрЩо цеПриклад
    hostАдреса сервера СУБДdb.stage.example.com
    portМережевий порт5432 (PostgreSQL)
    databaseІм'я бази всередині СУБДshop
    userОбліковий записqa_readonly
    passwordПароль(з менеджера секретів)
    ssl / sslmodeЧи шифрувати з'єднанняrequire

    Порти за замовчуванням варто впізнавати: PostgreSQL — 5432, MySQL/MariaDB — 3306, SQL Server — 1433, Oracle — 1521. Це дефолти; на конкретному стенді порт може бути іншим.

    Той самий набір часто пакують в один URL-подібний рядок підключення (connection string):

    postgresql://qa_readonly:password@db.stage.example.com:5432/shop

    а в консолі це виглядає так:

    psql -h db.stage.example.com -p 5432 -U qa_readonly -d shop

    Доступи (адресу, логін, пароль) дає команда — зазвичай DevOps або тимлід. Два правила гігієни: паролі до баз не хардкодять у тестах і не комітять у репозиторій (це секрети), а для автотестів параметри підключення беруть з оточення. До підключення з коду поруч із Playwright ми ще повернемося у главі Тестові дані і БД в автотестах.

    Read-only дисципліна на стейджі й проді

    Це найважливіший абзац глави для trainee. Правило звучить просто: на спільних стендах, і особливо на проді, тестувальник тільки читає. Причина — у природі середовища. Прод містить реальні дані реальних користувачів; помилкова зміна там миттєва, видима всім і часто необоротна. Немає кнопки Ctrl+Z для бази, у якій ти щойно зіпсував тисячу рядків.

    Класична катастрофа — модифікуючий запит без умови. UPDATE чи DELETE без WHERE зачіпає всі рядки таблиці, а більшість клієнтів застосовують зміну одразу (autocommit увімкнений), тож відкотити нема як. Одна забута умова — і всі замовлення в базі змінили статус. Саме тому команди зміни даних (INSERT, UPDATE, DELETE) — окрема тема з окремою дисципліною, глава Зміна даних: INSERT, UPDATE, DELETE.

    Чому SELECT безпечний? Бо він нічого не змінює — лише читає. Тому переважна більшість SQL у роботі QA — це SELECT, і починати вчитися теж варто з нього (SELECT: вибірка, фільтрація, сортування). Практичні звички, які варто виробити з першого дня:

    • Проси окремий обліковий запис лише для читання (read-only user). Тоді СУБД фізично не дасть тобі щось змінити — найнадійніший запобіжник.
    • Якщо тобі таки треба щось записати заради тесту — роби це лише на своїх ізольованих даних на dev/тест-середовищі, ніколи не на спільному стенді наосліп.
    • Перед будь-яким модифікуючим запитом спочатку виконай SELECT з тією самою умовою WHERE — подивися, які саме рядки зачепиш. Побачив 5000 замість 1 — зупинися.
    • Знай про транзакції як страхувальну сітку (BEGINROLLBACK), але пам'ятай, що при autocommit вона не спрацює автоматично — механіку розбирає глава Транзакції та ACID.

    І застереження, щоб не було хибного відчуття безпеки: read-only — це не «нульовий вплив». Важкий запит без обмеження на великій прод-таблиці може навантажити базу й зачепити живих користувачів. Тож на проді додавай LIMIT, не запускай важке в пік навантаження й, де можна, читай з репліки, а не з основної бази.

    Діалекти SQL коротко

    SQL стандартизований (ISO/IEC 9075), і ядро мови — SELECT, WHERE, JOIN, GROUP BY — приблизно однакове всюди. Але кожна СУБД має свій діалект: на краях синтаксис розходиться, і запит з однієї бази може не завестися в іншій. Ось найчастіші розбіжності, на які натикаються:

    ЩоPostgreSQLMySQLSQL Server
    ПагінаціяLIMIT 10LIMIT 10TOP 10 / FETCH FIRST
    АвтоінкрементSERIAL / IDENTITYAUTO_INCREMENTIDENTITY
    Конкатенація рядків`'a''b'`
    Лапки для імен"column"`column`[column]

    Практичний висновок один: перш ніж писати запит, знай, з якою СУБД працюєш. Запит із LIMIT впаде в SQL Server, а || у MySQL за замовчуванням означатиме не склеювання рядків, а логічне «або». У цьому розділі базовою СУБД для прикладів буде PostgreSQL (безкоштовна, дуже поширена в вебі), а там, де MySQL поводиться інакше, ми це окремо позначатимемо.

    Типові помилки

    • Виглядає як баг застосунку, а насправді ти дивишся не в ту базу. Дані «не збігаються» — а підключення вказує на dev замість stage, або на репліку, куди свіжий запис ще не доїхав. Перше, що варто перевірити при розбіжності, — до якого середовища й до якої бази ти реально під'єднаний.
    • Виглядає, ніби запис зник, а насправді це soft-delete. Через UI елемент пропав, але в базі рядок на місці — просто виставлено deleted_at або is_active = false. Застосунок його ховає, база — ні.
    • Виглядає, що SELECT безпечний завжди, а насправді ні. Змінити дані він не змінить, але важкий запит без LIMIT на прод-таблиці в мільйони рядків може підвісити базу для живих користувачів. Read-only не дорівнює no-impact.
    • Виглядає, що SQL один для всіх, а насправді це діалект. Запит, скопійований зі StackOverflow під іншу СУБД, падає з незрозумілою помилкою синтаксису — бо там був TOP, а тут потрібен LIMIT.
    • Виглядає, що NoSQL — це «база без правил», а насправді просто інші правила. Відсутність фіксованої схеми не означає, що будь-які дані валідні; вона означає, що перевірку форми даних застосунок робить сам — і саме там ховаються баги «поле раптом відсутнє».

    Підсумок

    • База даних — джерело істини. UI й API вже інтерпретують дані; коли цифри не збігаються, остаточну відповідь дає SQL напряму в базі.
    • СУБД — це сервер, до якого можна під'єднатися напряму. Клієнтом (psql, DBeaver, DataGrip) в обхід застосунку, маючи набір параметрів: host, port, database, user, password.
    • SELECT читає й нічого не змінює — це безпечна й найчастіша операція QA; UPDATE/DELETE без WHERE — необоротна катастрофа.
    • На проді й спільних стендах — тільки читання, бажано з read-only облікового запису; read-only все одно не означає нульовий вплив на навантаження.
    • SQL стандартизований, але має діалекти: ядро переносне, краї (пагінація, автоінкремент, конкатенація) різняться між PostgreSQL, MySQL і SQL Server.

    Що питають на співбесіді

    • «Навіщо тестувальнику SQL? Коли ти лізеш у базу?» Інтерв'юер хоче почути не визначення, а сценарії: звірити дані з UI, підготувати стан, розслідувати баг, побачити приховане. Сильна відповідь — про базу як джерело істини.
    • «Що безпечніше — SELECT чи UPDATE, і чому на проді треба бути обережним?» Тут перевіряють здоровий глузд і повагу до продакшену. Червоний прапорець для інтерв'юера — кандидат, який спокійно каже «та я просто зроблю DELETE». Правильно — згадати read-only дисципліну й пастку WHERE.
    • «Чим реляційна база відрізняється від NoSQL?» Очікують: таблиці й фіксована схема проти гнучкої, SQL проти власних API, сильна цілісність проти масштабу/гнучкості. Бонус — що це різні інструменти, а не «старе проти нового».
    • «Як ти під'єднаєшся до бази — що для цього потрібно?» Перевірка практичності: host, port, database, user, password; який клієнт; що доступи беруться в команди, а не хардкодяться.
    • «У чому різниця між БД і СУБД?» Просте питання-фільтр: база — це дані, СУБД — програма, що ними керує.

    Джерела

    • PostgreSQL: The SQL Language (tutorial) — базовий вступ у SQL від офіційної документації PostgreSQL.
    • PostgreSQL: psql — референс консольного клієнта й параметрів підключення.
    • MySQL 8.0 Reference Manual — офіційна документація MySQL, зокрема відмінності діалекту.
    • DataGrip Help — робота з базами в GUI-клієнті: підключення, запити, редагування даних.