← Python мануфактура

Після цього уроку ви зможете

Конспект і таймкоди

0:00

Коли прямий DB access справді прискорює тести

Створення або читання сутності через API проходить routing, application logic, database access і serialization, тому сотні setup-запитів накопичують час. Прямий запит до database інколи виконується за кілька мілісекунд і може бути корисним для підготовки або пошуку test data.

У Java типовим низькорівневим контрактом є JDBC; у Python — драйвер конкретної СУБД, який зазвичай підтримує Python DB-API. Для підключення потрібні host/URL, database/schema, credentials і driver. Секрети не мають бути в коді, а тестовий користувач БД повинен мати мінімальні права.

Прямий insert не завжди еквівалентний product operation: він може обійти validation, events, audit, caches та синхронізацію. Тому DB setup доречний лише для сутностей, де команда явно приймає такий контракт.

Увага

Direct insert не дорівнює product operation

DB setup може обійти validation, events, audit, cache invalidation і зовнішню синхронізацію. Використовуйте його лише там, де команда явно прийняла direct database contract для test support.

Термін

DB-API `threadsafety`

Integer capability level у Python DB-API module. Значення окремо визначає, чи threads можуть share module, connections і cursors; DB-API compatibility сама по собі не гарантує безпечний shared connection.

Термін

SQL parameter binding

Передача values окремо від SQL statement через placeholders і driver API. Це зберігає type handling і не складає query через string formatting.

Приклад коду

Ізольований DB setup із parameter binding

import sqlite3

with sqlite3.connect(":memory:") as db:
    db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT UNIQUE)")
    db.execute("INSERT INTO users(email) VALUES (?)", ("qa@example.test",))
    row = db.execute("SELECT id FROM users WHERE email = ?", ("qa@example.test",)).fetchone()
    assert row == (1,)

Використовує in-memory database, connection context manager і placeholders без зовнішніх dependencies.

Очікуваний результат: Assertion проходить; query повертає row (1,).

Практика

Вибрати правильний test seam для persistence

  1. Для одного business flow перелічіть validation, events, audit і data transformations між API та database.
  2. Визначте, які properties доводить unit, integration та end-to-end test.
  3. Якщо direct DB setup залишається, задайте connection ownership, transaction boundary і cleanup для parallel workers.

Результат: Test matrix без дублювання framework behavior і з явним direct-DB ceiling.

3:30

Entity, DAO, repository та ORM

Entity object відображає таблицю або persistence-модель, DAO інкапсулює низькорівневий доступ до даних, а repository формулює операції мовою домену, наприклад findUserByEmail. Межі цих назв різняться між ecosystem, тому важливіше розуміти відповідальність, а не механічно відтворювати всі шари.

ORM перетворює об'єкти на relational data та генерує SQL. Він зменшує кількість ручних queries для стандартного CRUD, але не скасовує знання schema, indexes, transactions і joins. Для невеликого test-support helper достатньо вже наявного driver/repository; окремий ORM-шар лише для тестів часто створює дублювання production model.

6:30

Що перевіряти замість повторного тестування СУБД

Якщо застосунок використовує зрілий framework і ORM, automation suite не має доводити, що framework у принципі вміє зберігати рядок. Цінність дають перевірки власної конфігурації: migrations, column types, precision, foreign keys, transaction boundaries, custom queries і mapping між database та API.

Часто API або UI test уже опосередковано проходить database integration. Окремий DB assertion потрібен, коли зовнішня відповідь не доводить важливу властивість persistence — наприклад audit record, точність money value або асинхронний статус.

Для dashboards, statistics і Big Data ключовою є не сама таблиця, а правильність агрегації: joins, filters, rounding, time zones і перетворення backend. Тут доцільно порівнювати результат із контрольованим dataset або незалежно обчисленим oracle, а не дублювати той самий SQL у тесті.

Термін

Foreign key

Database constraint, який вимагає, щоб value у referencing columns відповідало row у referenced table, підтримуючи referential integrity.

10:30

Комбінований UI/API/DB framework і архітектурний рівень

Framework, який одночасно керує UI, API та DB, вимагає чітких lifecycle і ownership: окремі clients, ізольовані test data, безпечний connection pool, cleanup і коректна робота в parallel. Додавати всі рівні до кожного тесту не потрібно; кожен сценарій має використовувати найнижчий seam, який доводить потрібну поведінку.

На senior-рівні додаються system architecture, protocols, caching і concurrency. В event-driven системах доводиться спостерігати Kafka, RabbitMQ або інший broker, чекати eventual consistency та корелювати події. Stub service корисний для контрольованих failure/edge cases, але не замінює невеликий набір справжніх integration tests.

14:30

Test trophy і правильний розподіл перевірок

У відео test trophy протиставляється механічній testing pyramid: в основі quality gates лежать static analysis і security checks, далі — швидкі unit tests, ширший шар integration tests і невелика кількість end-to-end scenarios. Ідея — інвестувати в той рівень, де система має найбільший ризик і де перевірка дає швидкий надійний сигнал.

Важливе уточнення: не слід зменшувати unit coverage лише тому, що продукт використовує Spring, Django або готову database. Не потрібно тестувати код framework; потрібно unit-тестувати власну чисту domain logic, а integration tests залишити для mappings, transactions, SQL, serialization та зовнішніх contracts.

17:00

ORM trade-offs і вибір першого automation seam

ORM є компромісом: прискорює типову розробку, але може генерувати неефективні queries або приховувати N+1, зайві joins і transaction behavior. Повертатися до ручного SQL слід за профілем і вимірюванням, а не через загальну недовіру до abstraction.

У бажаній архітектурі backend виконує бізнес-перетворення, а frontend переважно відображає готовий contract. Якщо значна logic усе ж живе на frontend, це підсилює цінність UI/component automation. Коли продукт створюється з нуля й UI ще немає, логічно почати з API. Для наявного продукту без automation перший seam вибирають за ризиком і вартістю ручної регресії, а не за універсальним правилом «завжди UI» або «завжди backend».

Джерела та додаткові матеріали

  • PEP 249 — Python Database API Specification v2.0 ↗Python Software Foundation / Python Enhancement Proposals · перевірено 2026-07-31

    Фіксує connection/cursor contract, threadsafety і paramstyle capabilities.

  • PostgreSQL Constraints ↗PostgreSQL Global Development Group · перевірено 2026-07-31

    Описує primary, unique, check і foreign key constraints та referential actions.

  • Python `sqlite3` ↗Python Software Foundation · перевірено 2026-07-31

    Дає runnable stdlib seam для transaction і parameter binding examples.