Совет дня №30
В прошлом совете упоминались чистые функции в базе. Разумеется, их нужно тестировать. Для Постгреса написаны свои тестовые фреймворки, но ими пользуются при разработке расширений. Обычные функции тестируют в приложении: вызывают функцию и проверяют, что она вернула.
Например, в базе есть функция для форматирования центов:
create or replace function format_cents(cents integer)
returns text
immutable strict parallel safe language sql
return to_char(cents, '999.999');
Тест посылает такой запрос:
select
x,
format_cents(x) as result
from (values
(1), (999), (null), (0), (-42)) as vals(x);
Читаем результат и проверяем, что он следующий:
┌────────┬──────────┐
│ x │ result │
├────────┼──────────┤
│ 1 │ 1.000 │
│ 999 │ 999.000 │
│ <null> │ <null> │
│ 0 │ .000 │
│ -42 │ -42.000 │
└────────┴──────────┘
Вот и все. Если кто-то поправит функцию, тест упадет.
Сложную логику тестируют точно так же. Достаточно нескольких шагов:
- положить нужные данные в базу;
- запустить целевую функцию;
- проверить, что данные изменились должным образом;
- почистить за собой.
Функция удобна тем, что данные не нужно готовить. Передал — получил. База фактически не участвует. А для сложной логики нужно готовить данные.
К счастью, для этого есть фикстуры — функции, которые выполняются до или после
теста, причем в разрезе всего набора или отдельного теста. Поэтому пишутся
фикстуры, которые поднимают базу, накатывают тестовые данные, а в конце делают
TRUNCATE по всем таблицам.
Базу обычно запускают в Докере, потому что в нем многое можно задать из коробки (базу, пользователя, пароль, начальные .sql файлы и другое). Кто не любит Докер, пусть ставит локальный Постгрес — он есть везде.
На этом месте начинаются вопли: мол, тесты-то не юнит-, а интеграционные! Ну и что? Юнит-тесты нужны, но порой их недостаточно. Когда сетевые вызовы закрыты моками, легко оказаться в мире Оруэлла: дважды два равно пяти. Тесты пробегают, прод падает.
Так что если у вас Постгрес — тестируйте, как приложение ходит в Постгрес.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter