🖥 Cовет по SQL-тестам: тестируйте не только результат запроса, а его инварианты. — 10 мая 2026 г. в 14:50:02.645
🖥 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-тест проверяет не только ответ, а свойства запроса, которые должны оставаться истинными при любых данных. Именно так ловятся баги, которые не видно на маленьком тестовом датасете.

