Лишнее поле в ответе, которое никто не замечает
Когда сверяешь ответ с документацией, обычно идёшь по списку из доки. Поле на месте, тип подходящий, значение похоже на правду, дальше. Так ловится отсутствие того, что должно быть, но совершенно не ловится появление того, чего быть не должно.
По документации ответ выглядит так:
{ "traceId": "7c2a8410-56f2-4f59-b921-202607230001", "orderId": "ORD-2026-0723-001", "status": "CREATED", "customerId": "C-1042", "pricing": { "subtotal": 51960, "discount": 5196, "total": 46764, "currency": "RUB", "vatAmount": 0 } }
А это то, что реально пришло со стенда:
{ "traceId": "7c2a8410-56f2-4f59-b921-202607230002", "orderId": "ORD-2025-0723-001", "stats": "CREATE", "customerId": "C-1042", "pricing": { "subtotal": 51960, "discount": 5196, "total": 46764, "curency": "RU", "price": 46764 } }
Засеките тридцать секунд и посчитайте расхождения. Девять полей, глазами — ровно так, как это делается в реальной задаче.
⁂
⁂
⁂
Восемь!
traceId заканчивается на 0002, а ждали 0001 — ответ пришёл не на наш запрос.
В orderId стоит 2025 вместо 2026.
Поля status нет: вместо него stats,
значение CREATE вместо CREATED.
Поля currency нет: вместо него curency,
значение RU вместо RUB.
Поле vatAmount пропало совсем.
Появилось поле price, которого в документации нет.
Все три суммы совпали, и глаз расслабляется именно там, где надо смотреть внимательнее.
В блоке pricing по документации пять полей, а в ответе приехало шестое: price. Сверка по списку из документации его не показывает — по определению: ты идёшь по перечню известных полей, а незнакомого в перечне нет. Плюс значение в нём совпадало с total, так что даже случайный взгляд ни за что бы не зацепился. Разошлись они позже, когда логику расчёта поправили, и к тому моменту это поле уже читал клиент.
Штука в том, что лишнее поле редко бывает безобидным. Обычно это либо внутренний флаг, который случайно вылез наружу, либо отладочное значение, либо данные, которых в публичном ответе быть не должно вообще. И глазами такое ловится ровно один раз, на самом первом ответе, пока смотришь внимательно.
Я закрыл это одной проверкой. Перечислил, какие ключи разрешены на каждом уровне вложенности, и потребовал, чтобы других не было. Дальше она работает сама и краснеет, когда в ответе появляется что-то новое. В том числе когда поле честно добавили в документацию, а мне сказать забыли — тоже полезно узнать.

Собирал я это без кода, в своём настольном приложении под Windows. Указываешь путь к параметру, оператор, ожидаемое значение из документации, при желании тип данных — и всё. Запускается руками, из CI не работает, так что если у вас уже есть автотесты и человек, который их пишет, вам это неинтересно, у вас задача решена лучше.
Мне сейчас не хватает взгляда со стороны, особенно ручных тестировщиков и аналитиков. Если вы тоже проверяете API руками и автотестов у вас нет, расскажите в комментариях, как вы ловите такие расхождения. А если захочется посмотреть на инструмент вживую, напишите мне, я покажу и дам доступ, он бесплатный.

