Тесты — один из важных инструментов проверки ИТ-продуктов и обновлений на работоспособность, наличие уязвимостей, багов и других проблем. Поэтому написание тестов неотъемлемая задача в контексте поддержки и развития любых проектов. Но часто самих тестов недостаточно — если проект большой, то ручной запуск и контроль может стать непосильной ношей. Поэтому лучшая практика: автоматизация тестирования и оптимизация написания автотестов.
Привет, Хабр. Меня зовут Антон Нечаев. Я ведущий инженер обеспечения качества в MedTech-компании №1 в России — СберЗдоровье. В этой статье я расскажу, какие бывают нюансы при написании автотестов и как мы их решали, а также о том, как ускорили работу с тестами с помощью собственного плагина для IntelliJ IDEA.
Немного предыстории
ИТ-сервисы MedTech компании СберЗдоровье тщательно тестируются перед релизами любых обновлений — так мы гарантируем, что продукты компании соответствуют нашим требованиям и ожиданиям пользователей.
Причем наш путь к высокой степени покрытия собственных сервисов тестами был эволюционный. Так, по мере развития компании и увеличения задач для команды тестировщиков, мы изначально начали автоматизировать уже существующие тесты самостоятельно, а после и вовсе решили ускорить автоматизацию с помощью любых доступных инструментов. Чтобы решить эту задачу, мы погрузились в исследования.
Исследование проблемы
Чтобы определить точки роста и ускорить автоматизацию, нам надо было подробно проанализировать, как именно она реализована изначально. К этой задаче мы подошли комплексно.
Разбили написание теста на этапы. Таких этапов оказалось три: описание шагов, добавление ассертов, подготовка вспомогательных классов (Dao, Dto).
Замерили время, которое уходит на каждый из этапов.
Проанализировали, на что тратим больше всего времени.
В результате анализа мы обнаружили существенный дисбаланс:
10% времени у нас уходит на основные шаги;
10% времени — на написание ассертов;
80% времени занимает подготовка вспомогательных классов.

В свою очередь, внутри этапа подготовки вспомогательных классов всего до 25% уходит на DTO, и целых 75% — на Entity классы для взаимодействия с БД.

Опустившись ещё на уровень ниже, мы заметили, что 70% времени в рамках задачи подготовки Entity классов уходит на на прокачку новой экспертизы сотрудников в разных аспектах (например, как написать core, построить класс, использовать аннотации, строить связи) и только 30% — на написание самих классов.

Способы оптимизации и поиск инструмента
Самый очевидный способ ускорения создания вспомогательных классов — найм дополнительных автоматизаторов. В теории это даст команде новые силы и позволит повысить общую производительность. Но мы решили идти другим путем. А именно — попробовать использовать генерацию. Соответственно, нам надо было найти инструмент, который сможет решать наши задачи, и будет удовлетворять нескольким запросам. Так, мы хотели, чтобы искомое решение предоставляло:
удобство использования;
нативность технологий и их совместимость с IntelliJ IDEA;
возможность бесплатного использования;
отсутствие необходимости в доработках, чтобы снизить порог входа в работу с инструментом и упростить онбординг новых тестировщиков;
отсутствие необходимости в дополнительных технологиях, чтобы не делать проект зависимым от чего-то в обязательном порядке;
возможность гибкой настройки;
простой и понятный алгоритм ввода данных.
На соответствие этим требованиям мы изначально проверили три наиболее распространенных инструмента:
Intellij idea Ultimate;
Amplicode;
Hibernate plugin.

Но уже после первого детального ревью стало очевидно несколько моментов:
IntelliJ IDEA Ultimate требует доработки классов и стоит около $600 за одну годовую лицензию.
Amplicode также требует доработки классов. Более того, для работы с ним нужны дополнительные технологии — а именно, Spring.
Hibernate plugin подразумевает работу через консоль и, также, предполагает доработку классов.
Поскольку ни один из вариантов не отвечал нашим требованиям «из коробки», мы решили не погружаться в доработки, а создать свой генератор.
Создание своего генератора
Первое, с чего мы начали проработку своего генератора — выбор варианта представления. Так, потенциально его можно реализовать несколькими способами.
HTML-страница для работы через браузер. Вариант хороший, но недостаточно интуитивно понятный и не совместим с IDEA.
Jar-файл. Но в таком случае придется работать через консоль, что существенно повышает порог входа.
Плагин. Наиболее интуитивный и простой для внедрения в стек команды вариант.
Мы остановились именно на формате плагина. При этом нам было важно, чтобы с ним могли работать даже специалисты без глубокой экспертизы, а сам плагин позволял генерировать Entity классы любой сложности.
Интегрировать этот плагин мы решили в контекстное меню папки.

Здесь меню Generate, которое в дальнейшем может стать роутером для новых фич, будет наиболее уместным для тестировщиков.

Первый успех
Разработанная первая версия плагина получилась вполне функциональной:
с одной стороны, она позволяла вводить данные для подключения БД и проверять подключение;

с другой стороны — давала возможность указывать названия таблиц для генерации, дополнительные настройки, маппинг типов данных и дополнительные аннотации классов.

При этом, после первых тестов генератора на реальных задачах, мы собрали обратную связь, исходя из которой стало очевидно несколько моментов:
более востребованный вариант — хранить несколько подключений к БД, чтобы не вводить повторно данные подключения;
специалистам не всегда удобно указывать название таблиц от руки, из-за чего они могут сталкиваться с ошибкой «Не найдена таблица»;
некоторые специалисты хотят иметь возможность менять тип переменной для отдельных полей;
есть запрос на добавление enum в качестве внутреннего класса;
команде не всегда очевидно, как добавить аннотацию к классу через настройки.
Чтобы закрыть эти запросы и потребности команды, мы начали доработку плагина.
Плагин v2.0
В новой версии плагина мы постарались реализовать все выявленные точки роста, чтобы сделать инструмент более интуитивным, функциональным и удобным.
Так, обновленный плагин для генерации Entity классов дополнительно получил:
меню добавления/редактирования/удаления подключения;
дополнительные настройки;
поле для поиска таблиц;
поле для отображения списка таблиц;
поле для отображения данных о таблице.

Одновременно с этим мы закрыли основные потребности и отработали возражения, возникающие у команды при работе с первой версией плагина.
Так,
теперь не надо постоянно повторно вводить данные подключения — их можно сохранить и выбирать из списка;

трудности с написанием наименования таблиц минимизированы — названия можно выбрать из списка с подсказками;

ввод аннотаций сделан шаблонным, чтобы исключить ошибки ввода;

предусмотрена возможность точечного изменения параметров генерации;

можно использовать перечисление внутренними классами.

Полученные результаты и итоги
Проделанная работа в части оптимизации подготовки автотестов позволила нам существенно снизить затраты времени на создание Entity классов — если раньше на него приходилось 75% по отношению к созданию DTO классов, то сейчас показатель метрики снизился до 5%, то есть в 15 раз.

Это позволило снизить и общие затраты времени на вспомогательные классы — теперь на них приходится всего 34% времени вместо 80%, как было изначально.

Наряду с получением буста в скорости подготовки инфраструктуры для автотестов и самих автотестов, мы также получили дополнительные преимущества, к которым можно отнести:
продвинутую экспертизу в генерации;
продвинутую экспертизу в создании Entity классов;
нативность технологии в виде плагина с поддержкой русского и английского языков;
генерацию Dao классов из данных БД;
множество дополнительных настроек;
возможность генерации теста из curl;
возможность обновлять имеющиеся классы в одно нажатие;
скорость и доступность инструмента.
При этом появились еще некоторые полезные фичи, о которых я расскажу в одной из следующих статей.
Таким образом, наш выбор в пользу самописного генератора дал значительный профит, чем в полной мере оправдал инвестиции времени и ресурсов, затраченные командой на разработку.