В интернетах удивительно мало информации о том, как технически устроить повышение уровня покрытия тестами на проектах, где по историческим причинам их писать было не принято. Обычно тесты пишут большие и крутые ребята, которые как-то раз это завели у себя и не видят смысла зачем об этом рассказывать. А если и рассказывают, то это непросто на себя переложить.
Вот вы решили писать тесты. Предположим, что вы придумали весь стек на котором будете это делать. Хотя это тоже ещё та задача. Там и фреймворков много, и подходов в них, и даже каких-нибудь ассёрт-библиотек не одна и не две. Основная сложность не в том, что тесты писать нельзя, а в том, чтобы люди их реально писали.
Единственная понятная мне метрика – процент покрытия тестами строк кода. Для его сбора есть JaCoCo, и есть Kover. Первый – индустриальный стандарт, но не очень работает с котлином. Второй – хоть ещё не вышел в стабильной версии, но от JetBrains, с котлином в уме, и как будто сильно проще. Поэтому делаем ставку на него. Списать с документации просто не получится. Добавить сбор покрытия в каждый из ~200 модулей проекта – просто, но чтобы это собрать в один итоговый отчёт приходится повозиться. Сэмплы где-то на дне гитхаба и по знакомым ищешь.
Kover делает отчёты в JaCoCo формате, который довольно популярен, поэтому с какими-то дальнейшими интеграциями всё должно быть одинаково просто. И правда, в GitLab CI разбор этого отчёта добавить довольно легко, например. И вот уже на код ревью в гитлабе начинают подсвечиваться какие-то непокрытые строчки красным и в мёрж реквесте гордо красуется число – 2% покрытия по проекту. 😔
И в этом кроется следующая проблема. Что делать-то с этим? Нельзя так просто взять и сказать, что с завтрашнего дня без покрытия 80% мы ваши реквесты не смёржим. Разраб в своём мёрж реквесте вообще не причём, что проект не покрыт. Он должен отвечать только за свой конкретный реквест. Покрытие проекта хоть и интересная, но бесполезная штука, т.к. ты с этим числом ничего не сделаешь. Ладно бы это был новый проект, на котором можно было бы сразу требуемый процент зафиксировать. Но у нас-то старый.
Так я и пришёл к мысли, что ключевая метрика – процент покрытых строк именно на уровне конкретного мёрж реквеста. Мы должны требовать от разработчиков, чтобы они свои новые/изменённые строки покрывали на целевые 80%. А как это сделать, если у нас отчёт на весь проект и GitLab это сам считать не умеет?
Задача, казалось бы, алгоритмически простая – взять дифф, взять JaCoCo отчёт, посчитать количество покрытых строк из диффа относительно всех строк из диффа – вернуть процент покрытия. Наверняка кто-то делал, рискну даже предположить, что есть готовые GitHub Actions или какой-нибудь SonarQube умеет такое делать из коробки. Но что если у тебя их нет?
Поверхностный поиск показывает, что делали. Но решений становится ещё меньше и меньше, для тебя уже сотня звёзд на гитхабе в радость. Есть вот что-то типа такого или такого. Я уж даже не помню что с ними не так, но у меня никто из них не завёлся за несколько часов так как я хотел. Возможно я мало старался, но как будто возня несоразмерна задаче.
Если вы думали, что этот пост без AI агентов обойдётся, то вы ошибались. Я в результате пошёл и за несколько часов сгенерил себе Gradle-таску, которая принимает отчёт по покрытию, хэш коммита, по которому git diff запускает, и матчит строки с отчётом. На выходе одно число – процент покрытия на уровне диффа. И тесты нагенерил. И документацию. И CI конфиги поправил, чтобы запускалось. И это всё работает.
Ну а потом уже дело техники. Можем в danger, например, посмотреть на результат этой таски, похвалить разраба, если всё хорошо / сказать, что можно было бы лучше / сказать, чтобы он шёл и дописывал тесты, иначе не сольётся.
Велосипед – да. Решает задачу – да. Кайфанул ли я пока это писал – да. 🤟
А дальше развилка. Или вы мне говорите, что я неправ и надо было сделать так или эдак, накидываете материалов. Или я это простейшее решение собираю в репу на гитхабе, чтобы можно было подключить одной строчкой.