ТестированиеТестирование API и интеграцийИнженер по автоматизации тестирования интеграций

Тест интеграции проверяет JSON ответ только по схеме типов, но не сверяет сумму позиций с полем total. Како...

Тест интеграции проверяет JSON-ответ только по схеме типов, но не сверяет сумму позиций с полем total. Какой дефект такой тест может пропустить?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Такой тест может пропустить семантическое нарушение контракта: например, сервер вернёт числовые поля правильного типа, но значение total не будет равно сумме позиций. Проверка схемы подтверждает структуру и типы данных, однако не подтверждает бизнес-инварианты, связывающие несколько полей.

Исторический контекст

Схемы ответов появились как способ формально описывать структуру сообщений между независимыми системами: обязательные поля, типы, допустимые форматы и вложенность. Это устраняет часть ошибок интеграции, связанных с несовместимым JSON.

Однако структурная проверка не отвечает на вопрос, согласованы ли значения между собой. Поэтому поверх схемы используют семантические проверки — утверждения о смысле данных и отношениях между их полями.

Постановка проблемы

Сервер может вернуть массив позиций, корректные числовые значения цены и количества, а также поле total типа «число». Формально такой ответ соответствует схеме даже в случае ошибки расчёта, округления, применения скидки или включения лишней позиции.

Если интеграционный тест проверяет только схему, дефект обнаружится поздно: его может заметить пользователь, бухгалтерская система или другой сервис-потребитель. Особенно опасна ситуация, когда разные сервисы самостоятельно пересчитывают итог и получают разные суммы.

Подробное решение

Интеграционный тест должен проверять не только структурный контракт, но и релевантные семантические инварианты. В данном случае нужно определить бизнес-правило: например, total равен сумме позиций с учётом документированных скидок, налогов и правил округления.

Проверка должна использовать независимый от реализации расчёт теста. Нельзя просто вызвать тот же production-код вычисления суммы, потому что одинаковая ошибка в коде приложения и тесте даст ложный успех.

Важно явно зафиксировать правила:

  • на каком этапе применяется скидка;
  • включены ли налоги и доставка;
  • в каких единицах и с какой точностью передаются деньги;
  • выполняется ли округление по каждой позиции или после суммирования;
  • допускается ли небольшая погрешность для чисел с плавающей точкой.

Для денежных значений обычно предпочтительны целые минимальные единицы валюты либо десятичная арифметика. Если контракт допускает расхождение из-за округления, тест должен проверять документированный допуск, а не произвольное точное равенство.

Семантические проверки не заменяют схему. Схема быстро выявляет отсутствие поля или неверный тип, а инварианты проверяют согласованность и смысл данных. При этом не следует дублировать все внутренние правила сервиса: интеграционный тест должен проверять только внешний контракт, значимый для потребителя.

Ситуация из практики

Интеграционный тест заказа проверял наличие идентификатора, списка позиций, цен и итоговой суммы, а также соответствие JSON-схеме. После изменения расчёта скидки тест продолжил проходить, хотя клиент показывал покупателю сумму без учёта скидки, а платёжный сервис списывал другую сумму.

Рассматривались два варианта. Первый — проверять только фиксированный полный ответ; это просто, но плохо выявляет причину ошибки и делает тест хрупким при допустимых изменениях данных. Второй — проверять независимые инварианты: состав позиций, правила скидки, итоговую сумму и формат денег; такой подход требует точнее описать контракт, зато отделяет бизнес-дефект от косметических изменений ответа.

Выбрали второй вариант: тест создавал заказ с несколькими позициями, скидкой и пограничным округлением, затем независимо рассчитывал ожидаемые значения по правилам внешнего контракта. В результате ошибка порядка округления была обнаружена на интеграционном уровне до выпуска, а тест не зависел от внутренней реализации расчётного модуля.

Что кандидаты часто упускают

1. Достаточно ли сравнить total с суммой цен всех позиций?

Нет. Нужно учитывать полный контракт расчёта: количество, скидки, налоги, доставку, валюту и правила округления. Простая сумма цен может сама быть неверной ожидаемой моделью и создать ложные падения теста.

2. Почему нельзя переиспользовать в тесте функцию расчёта из production-кода?

Если функция содержит дефект, тест воспроизведёт тот же дефект и подтвердит ошибочный результат. Независимая проверка должна быть проще и основываться на контракте, тестовых данных и явно заданных правилах, а не на том же алгоритме.

3. Нужно ли проверять все бизнес-инварианты в каждом интеграционном тесте?

Нет. Следует проверять инварианты, являющиеся частью внешнего контракта конкретного потребителя, особенно те, нарушение которых приводит к финансовым, юридическим или межсервисным ошибкам. Остальные правила лучше покрывать модульными или специализированными тестами, чтобы интеграционные проверки оставались понятными и не становились избыточно медленными.