Многие пишут, что «бутылочным горлышком» в агентной разработке являются люди, которые проверяют код. Я считаю, что это больше маркетинговое заявление, чем инженерное. Человек может выполнять код-ревью достаточно быстро. Уж точно быстрее, чем код проходит CI/CD пайплайн и деплоится на стенд. С ростом автоматизации, процесс код-ревью человеком сводится к:
— пробежаться глазами по неочевидным местам в коде, проверка которых ещё не покрыта автоматикой,
— проверить как отработала автоматика детерминированной проверки правил разработки.
У меня это занимает не больше 5-15 минут на пулл-реквест. «Бутылочное горлышко» я наблюдаю совсем в другом месте.
Сейчас агенты пишут код очень быстро. Это ускоряет разработку.
Так же быстро и в большом количестве агенты пишут тесты. Тесты — это хорошо, это фиксация контрактов, соблюдение правил разработки и подтверждение того, что код делает то, что нам нужно. Мы заставляем агентов тестировать код и они делают это легко и быстро. Мы радуемся: количество кода растёт, система становится больше и не теряет надёжность.
Казалось бы, может ли что-нибудь пойти не так. Может и обязательно пойдёт не так.
Тестов становится слишком много. За пару лет существования моего проекта люди-программисты написали около 3000 тестов. Половина из них была написана мной в течение года. Я делал много рефакторинга (приводил приложение в порядок), обновлял версии библиотек со сломанной обратной совместимостью и нужно было много тестов как гарантия того, что функционал приложения я не поломал.
Затем наступила весна 2026 года и к работе подключились агенты. Количество тестов с марта по ноябрь выросло с 3000 до 7200. Сложные интеграционные тесты стали для нас почти бесплатными и их стало очень много.
Тесты стали потреблять слишком много ресурсов. На тестовом стенде появились: OOMError, исчерпание памяти в базе данных, исчерпания лимитов локов и коннектов к базе данных. И чем больше у нас становилось тестов, тем медленнее они выполнялись. Если весной полный прогон тестов занимал 10-15 минут, то осенью он замедлился до 45 минут.
Чем быстрее агенты писали код и тесты, тем медленнее они начинали писать код — из-за необходимости запускать тесты 3-5 раз за одну задачу, время выполнения задачи выросло с 30-60 минут весной до 3-4 часов осенью. Через год тестов станет кратно больше и уже сейчас понятно, что выполнение задач кратно замедлится.
Пришлось задуматься над тем, как можно сократить время, которое расходуется на тесты, и при этом не потерять смысл в наличии тестов. Ведь самый простой вариант не тратить время на тесты — это не запускать тесты. Но тогда какой в них смысл?
Можно попробовать следующие способы ускорения тестов:
1. Запретить агенту тестировать очевидные вещи. Такие тесты я называю бестолковыми. К ним относятся тесты:
— факта применения скриптов миграции,
— факта добавления нового значения в enum,
— факта изменения в проекте списка зависимостей,
— и т.п.
2. Запретить агенту писать тесты-дубли.
Тесты-дубли делают одно и то же. Но первый тест проверяет поле createdAt, а второй — createdBy у той же структуры (объекта, таблицы). Такие проверки нужно объединять в один тест. Если поискать, то можно легко найти скилл аудита тестов, который можно добавить своему агенту как отдельный скилл и как правило написания тестов и выполнения код-ревью.
3. Поднимать контекст вашего приложения только один раз на все тесты. Статей про это написано много, для разных фреймворков — разобраться будет несложно.
4. Использовать для тестов базу данных на хосте, а не в тест-контейнерах.
Экономим: на памяти докера (актуально для маков), на времени старта тест-контейнеров и накатывания с нуля схемы базы данных для каждого теста.
Теряем: уверенность в том, что проект в любой момент сможет запуститься на чистой базе данных. Ещё неудобно, если схема базы данных отличается в разных git-ветках — при переключении между ветками, нужно будет готовить базу к тестам руками или прописывать для этого сложную автоматику.
5. Для всех тестов накатывать схему базы данных только один раз.
6. В тестах очищать базу данных не через [delete from …], а через откат транзакции. Транзакция начинается перед тестом, а после теста — откатывается. Это занимает 3-4 миллисекунды (почти даром). Но подходит не для всех тестовых фреймворков. Тестируемый код может выполнять свои транзакции на другом connection к базе данных. В этом случае транзакция, начатая тестом, не откатит изменения, внесённые в базу данных тестируемым кодом. Ещё это плохо сочетается с параллельным выполнением тестов и тестами взаимных блокировок.
7. Отключать триггеры перед очищением таблиц в тестовой базе данных. У меня это сократило время прогона всех тестов на 15 минут.
8. При написании кода запускать только те тесты, которые проверяют код, затронутый задачей.
Прогон 10-20 интеграционных тестов вместо 7200, занимает у агента 3-5 минут.
9. В пайплайне тесты можно ускорить, если поколдовать с режимом энергосбережения ядер процессора.
Удачи вам и помните: чем быстрее проходят тесты, тем быстрее идёт разработка.
ссылка на оригинал статьи https://habr.com/ru/articles/1103328/