Агент сообщил «тесты прошли», но тестов было ноль

После правки агент пишет в отчёте: «Тесты прошли». В CI зелёная галочка. Но изменённый компонент никто не проверил: скрипт запустил Vitest с фильтром старого имени пакета, нашёл ноль файлов и завершился успешно из-за --passWithNoTests. Exit code 0 сообщает, что команда выполнила свой контракт; он не доказывает, что был запущен хотя бы один нужный тест.

Сверьте команду, выборку и результат

Попросите агента привести точную команду из терминала, рабочую директорию и итоговую строку раннера: число test files, tests passed, skipped и failed. Сравните фильтр с реальными именами файлов. В монорепозитории важно знать, из какого package запускали скрипт и какой workspace-конфиг использовался. Команда vitest run billing фильтрует пути тестовых файлов, а не смысл слова «billing» в коде. Если тесты лежат под новым именем payments, выборка будет пустой.

Vitest по умолчанию не должен считать отсутствие тестов успехом, но опция passWithNoTests разрешает зелёный результат при нулевой коллекции. Она может быть нужна в отдельных пакетах монорепозитория, где тестов пока нет. Для CI-гейта изменённого пакета задайте отдельное правило: если этот пакет должен иметь тесты, число собранных тестов должно быть больше нуля. В pytest пустая коллекция имеет отдельный exit code 5; если shell-скрипт глотает его через || true, смысл сигнала тоже теряется.

Привяжите тест к изменению

Проверка числа тестов нужна, но недостаточна. Если агент менял packages/payments/src/refund.ts, а 20 прошедших тестов относятся только к apps/web, покрытие задачи всё равно не доказано. Назовите хотя бы один test file, который проверяет изменённую функцию или публичный сценарий, и откройте его assertion. В отчёте агента полезны четыре поля: точная команда, число собранных тестов, их идентификаторы/файлы и вывод результата. Это позволяет редактору изменения быстро увидеть пустой или нерелевантный прогон.

Сделайте контролируемую проверку: временно задайте фильтр, который точно не совпадает ни с одним файлом. С включённым passWithNoTests CI может остаться зелёным — значит, нужен отдельный gate по счётчику. Затем верните правильный фильтр и убедитесь, что выбран ожидаемый test file. Не подменяйте таким тестом полный регресс: целевой прогон отвечает за изменённый модуль, общий suite — за совместимость с остальным приложением. Проверку окружения дополните разбором зелёных тестов в неверной среде.

В платном курсе Vibecoding: Claude Code, Codex, Cursor и agentic development вы ставите агенту критерии готовности, используете его для тестов и проверяете полученный diff. Требование «назови собранные тесты» превращает расплывчатое «всё зелёное» в проверяемый результат. Откройте программу курса, чтобы оформить такие критерии для команды.

Продолжить на практике

  • Vibecoding: Claude Code, Codex, Cursor и agentic development ↗

    Практический курс по vibecoding и agentic development: Claude Code, Codex, Cursor и современные coding agents в реальной разработке. Вы научитесь запускать feature workflow через AI, работать с кодовой базой, ускорять debugging, tests и refactoring, делегировать агенту заметную часть разработки и при этом сохранять контроль над качеством, архитектурой и итоговым результатом.