Ввиду нестабильности ТЗ и принятия ряда решений на ходу (думаю, для многих знакомая ситуация), было принято решение покрыть код тестами после стабилизации основных пользовательских сценариев и ручной проверки критичных edge cases. Благо, хорошая декомпозиция проекта сводила к минимуму регрессии, но, естественно, не отменяла необходимости тестирования.
С появлением ChatGPT 5.2 использование его как помощника в написании тестов стало целесообразно. Подчеркну, что именно как помощника, когда мы говорим об объёмном контексте, а не покрытии класса, например, со строковыми утилитами — с этим справлялись и его предшественники. В процессе написания перешёл на свежий 5.4, но особой разницы не почувствовал.
Для меня рабочим сценарием создания промпта для unit-тестов стал следующий:
- Даю модели код тестируемого класса, начиная промпт с нижних уровней абстракции. Стоит добавить, что все методы имели javaDoc-описание, поэтому промптинг становился существенно проще.
- Добавляю DTO, enum’ы и зависимости, которые, очевидно, следует добавить.
- Спрашиваю у модели, что нужно ещё, и читаю описание её понимания происходящего.
- Пробегаюсь по результату, смотрю, что тестируем, и не является ли это откровенной синтетикой. Если надо, добавляю запрос на непроверенные edge cases.
- Запускаю тесты, правлю ошибки компиляции, если есть, далее разбираюсь с не прошедшими (их было примерно 5−7%).
- Перехожу на уровень выше и по горизонтали обхожу компоненты.
- В определённый момент (примерно на 30% от лимита токенов) модель начинала периодически сбоить, но не сильно — в основном забывала код, который уже был в контексте, и надо было его ей продублировать.
За interface-per-implementation anti-pattern замолвите словечко…
Требования к проекту включали использование интерфейса, описывающего поведение компонента, даже если этот компонент являлся его единственной реализацией. По моим субъективным наблюдениям, многим разработчикам такой подход претит, и я не исключение. Тем не менее написание в таком стиле позволило сделать промпты на большом контексте существенно лаконичней, потому что был готовый задокументированный код абстракций, которые инжектились в тестируемый компонент, а иногда это в совокупности могло составлять 1000+ строк кода, если бы мы добавляли реализации. Таким образом, я достаточно быстро набил руку в составлении промптов, учитывая, что я знал проект очень хорошо.