Тесты, статический анализ и ревью: чем проверять код, написанный ИИ
Когда модель предлагает патч, соблазнительно принять его после зелёного индикатора тестов. Но тесты могли не покрывать изменённый сценарий, статический анализ — не знать бизнес-правила, а ревьюер — не заметить редкий крайний случай. Эти методы не конкурируют за звание единственного правильного. Они проверяют разные свойства изменения. Ниже — сравнение на одном примере: ИИ переписал функцию, которая рассчитывает скидку в заказе.
Что именно ищем
Правильный патч должен сохранить арифметику, округление, порядок применения скидок, права пользователя, формат ответа и производительность на обычной нагрузке. Он не должен незаметно отправлять данные в сеть или расширять область изменений. Одного слова «работает» недостаточно: функция может проходить старые тесты, но менять логику для пустой корзины. Сначала запишите инварианты человеческим языком. Например: сумма не становится отрицательной, скидка не применяется дважды, итог совпадает с договорным правилом округления.
Удобно представить проверки как три вопроса. Тесты спрашивают: «Даёт ли код ожидаемый результат на заранее выбранных входах?» Статический анализ спрашивает: «Есть ли в тексте кода известные опасные конструкции и нарушения правил?» Ревью спрашивает: «Решает ли изменение нужную задачу безопасным и понятным способом?» Ответы пересекаются, но не заменяют друг друга.
Автоматические тесты: быстро, но ровно в пределах выборки
Хороший набор тестов проверит скидку 0%, граничное значение, возврат, несколько товаров, округление дробных сумм и повторный вызов. Тесты запускаются одинаково на каждом патче и дают воспроизводимый сигнал. Это особенно полезно, если ИИ меняет несколько строк и уверенно заявляет, что поведение сохранено. Однако зелёный набор может означать лишь отсутствие теста на новую ошибку. Если эталонный результат сгенерировала та же модель, она могла закрепить собственную неверную интерпретацию требования.
Перед принятием патча добавьте хотя бы один тест, который падает на старой проблеме и проходит на исправлении. Для чувствительной логики хорошо работает независимый расчёт в маленькой таблице. Не измеряйте качество только процентом покрытия строк: можно выполнить строку и не проверить значение. Подход к построению контрольной выборки подробнее разобран в гайде по тестовому набору для ИИ-поиска; в коде принцип эталона такой же, хотя инструменты другие.
Статический анализ: постоянные правила без понимания намерений
Линтер и анализатор безопасности могут заметить неиспользуемую переменную, опасную сериализацию, потенциальную инъекцию, вызов запрещённой функции или несоответствие типам. Они полезны как дешёвый обязательный фильтр перед ревью. Инструмент не устает и одинаково применяет установленное правило к каждому коммиту. Но он часто не знает, что скидка для определённого клиента должна считаться до налога. Он может выдать ложное предупреждение на безопасном шаблоне или пропустить логическую ошибку без известного сигнатурного признака.
Если проверка сообщает об уязвимости, воспроизведите путь атаки в контексте приложения. Автоматическая находка — повод исследовать, а не готовое заключение. Это особенно важно для новых модельных сканеров: разбор OSS Scanner показывает, почему поток отчётов требует сортировки и регрессионных тестов. Не удаляйте правило анализа только потому, что оно мешает одному патчу; сначала выясните, можно ли изменить код яснее.
Ревью человека: смысл, архитектура и ответственность
Ревьюер способен спросить, зачем функция вообще получила доступ к новому модулю, почему изменился контракт API и кто отвечает за миграцию старых данных. Он видит продуктовый контекст, которого нет в правилах линтера. Сильное ревью начинается с описания ожидаемого поведения и маленького diff, а не с чтения всех строк подряд. Попросите автора показать, какую проблему исправляет изменение, чем подтверждён результат и какие риски остались. Если патч подготовил ИИ, человек всё равно остаётся автором решения в инженерном процессе.
У ручного ревью есть пределы. Человек устает, может довериться знакомому стилю или не заметить баг в расчёте из десятков веток. Поэтому не заменяйте тесты комментарием «выглядит нормально». Для рискованных изменений назначайте второго ревьюера или проводите парную проверку на коротком списке инвариантов. Чем шире патч, тем труднее содержательно оценить его за один проход.
Как сочетать три метода без лишней бюрократии
Сначала ограничьте изменение одной задачей и сохраните требования. Затем запустите форматирование, типы, тесты и анализатор. Сравните результат с контрольным примером. После этого человек проверяет смысл, границы прав и план отката. Если ИИ добавил зависимости или сетевые вызовы, требуйте отдельного объяснения. Ошибки, найденные на ревью, превращайте в новый тест или правило, когда это возможно. Так стоимость следующей проверки снижается, а не растёт.
Для небольшой команды полезна матрица риска. Исправление подписи кнопки может пройти один ревью и базовый набор тестов. Расчёт денег, прав доступа или медицинских данных требует независимого эталона, специальных тестов и компетентного ревьюера. Не делайте вид, что три зелёные галочки равны доказательству безопасности. Их смысл — уменьшить число известных ошибок и сделать решение проверяемым. Общая дисциплина проверки на тестовом наборе применима и здесь: окончательное утверждение должно вести к конкретной проверке.
Вывод
Тесты хорошо проверяют ожидаемое поведение на заданных входах. Статический анализ дисциплинирует код и ловит известные опасные конструкции. Ревью человекa отвечает за смысл, архитектуру и неочевидные последствия. При коде, предложенном ИИ, нужен весь маршрут: эталон, автоматические сигналы, независимый взгляд и возможность отката. Выбирать один метод вместо остальных стоит только для задачи с действительно низкой ценой ошибки.
Частые вопросы
Если тесты зелёные, ревью всё равно нужно?
Да, если изменение влияет на продуктовую логику, данные или права. Тесты не проверят требование, которое никто не записал.
Можно поручить модели проверять собственный код?
Это полезная подсказка, но не независимое доказательство. Эталонные данные и окончательное решение должны быть отделены от автора патча.
Когда статический анализ даёт больше всего пользы?
Когда правила запускаются автоматически на каждом изменении и команда разбирает предупреждения, а не массово их подавляет.