🖥 Cовет по SQL-тестам: тестируйте не только результат запроса, а его…

🖥 Cовет по SQL-тестам: тестируйте не только результат запроса, а его инварианты.

Обычно SQL проверяют так:
SELECT * FROM orders WHERE status = 'paid';
И потом сравнивают: «вернулись нужные строки или нет».

Но в реальных системах чаще ломается не сам happy path, а скрытые свойства данных.

Например, для отчёта по заказам тест должен проверять не только конкретные строки, а правила:
-- сумма по пользователям должна совпадать с общей суммой
WITH by_user AS (
    SELECT user_id, SUM(amount) AS total
    FROM orders
    WHERE status = 'paid'
    GROUP BY user_id
),
overall AS (
    SELECT SUM(amount) AS total
    FROM orders
    WHERE status = 'paid'
)
SELECT
    (SELECT SUM(total) FROM by_user) = (SELECT total FROM overall) AS is_valid;
То есть вы тестируете не «мне вернулось 10 строк», а:

агрегаты не теряют деньги
join не размножает строки
фильтр не выкидывает валидные данные
NULL не ломает расчёты
сумма после группировки совпадает с суммой до группировки
каждый order попадает ровно в одну категорию
дедупликация не удаляет нужные записи

Особенно полезный приём - тест на размножение строк после JOIN:
WITH before_join AS (
    SELECT COUNT(*) AS cnt
    FROM orders
),
after_join AS (
    SELECT COUNT(*) AS cnt
    FROM orders o
    JOIN users u ON u.id
= o.user_id
)
SELECT
    after_join.cnt <= before_join.cnt AS no_unexpected_multiplication
FROM before_join, after_join;

Если после JOIN строк стало больше без явной причины - у вас почти наверняка проблема с кардинальностью.

Хороший SQL-тест проверяет не только ответ, а свойства запроса, которые должны оставаться истинными при любых данных. Именно так ловятся баги, которые не видно на маленьком тестовом датасете.
Просмотры: 1 137
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти