CI/CD для инженерного приложения
Краткое описание проекта

Одной из самых важных и сложно решаемых проблем на проекте являлось отсутствие стабильности. Поставки были нерегулярными, было сложно предсказать поведение приложении при изменении кода. Поэтому первым делом СЕО ДжазТим было принято решение внедрять автоматизированное тестирование в рамках CI/CD системы. Основными причинами внедрения автотестирования являлись следующие:
- Часто встречалась ситуация, когда изменения в одном модуле приложения вызывали регрессионные баги в другом модуле приложения.
- Приложение выполняет множество самых различных расчетов и unit-тестирование это самое логичное решение для обеспечения качества.
Важным фактором, влияющим на всю систему CI/CD является то, что каждый экземпляр приложения уникален, имеет свой уникальный серийный номер и уникальный аппаратный usb ключ защиты. Это накладывает следующие ограничения:
- Необходимость работы с аппаратными ключами.
- Разное поведение защищенного и незащищенного приложения.
- Отсутствие возможности полноценного автотестирования приложения на рабочем месте разработчика.
Continuous Integration и Continuous Delivery
В рамках Continuous Integration основной целью являлось создание ежедневной автоматической проверки качества через unit и ui тестирование. Нужно это для достижения следующих важных стратегических целей:- Сделать так, чтобы практически в любой момент времени был работоспособный билд приложения, содержащий в себе последние изменения.
- Сделать приложение стабильным. Добавление новой функциональности не должно ломать продукт.
- Уменьшить трудоемкость операций по багфиксингу и поставке новых приложений.
В рамках Continuous Delivery основными целями являлись:
- Автоматизация процесса поставки.
- Снижение влияния человеческого фактора.
- Улучшение процесса тестирования уже готовых экземпляров приложения перед их отправкой.
Постановка процессов
Для внедрения практики CI/CD также требовалась постановка управленческих процессов. Организация процесса работ — от постановки задач до тестирования, внедрение Scrum, изменение мышления команды.До прихода ДжазТим нормальной практикой на проекте было — сделать быстро, без документации и проработанного тестирования. Естественно, при этом приходилось тратить массу времени на поддержку из-за регулярных проблем при поставках. После нашего прихода, уже через 3 месяца, команда разработки, сохранив скорость создания нового функционала, начала сокращать технический долг и вести необходимую документацию. Как результат количество проблем при поставках существенно сократилось.
Обязательным этапом при разработке нового функционала стало его покрытие unit-тестами и ui-автотестами.
Ключевые достижениями на проекте за первые полгода:
- Существенное снижение рисков по возникновению багов при изменениях в существующем коде.
- Улучшение психологического климата в команде. Повышение мотивации к накоплению best practices и понимание, что усилия каждого человека действительно делают продукт лучше.
- Более грамотная работа с legacy-кодом, когда вначале компонент полностью покрывается интеграционными и ui-тестами и только после этого в него вносятся какие-либо изменения. Это сделало процесс разработки более прозрачным и предсказуемым.
- Уменьшение трудоемкости процесса разработки, связанное с ранним обнаружением багов и автоматизацией поставки ПО.
Блок-схема: Консультации по наукоемкой разработке продукта и построение процесса контроля качества
Unit-тестирование и интеграционное тестирование
Хорошая организация процесса тестирования позволила изменить мировоззрение команды на процесс разработки. Теперь правилом хорошего тона в команде считается при устранении бага полностью покрыть этот участок кода тестами, чтобы устранить саму возможность повторного появления бага. Также, как уже упоминалось выше, при серьезном вмешательстве в уже работающий компонент стало best practice вначале покрыть его тестами и только после этого вносить туда изменения.Так как система работает с научными данными, то одним из важных направлений тестирования стало активное применение data driven тестов. Таким образом мы смогли вовлечь в процесс тестирование всю команду проекта.
После каждого спринта фиксируются метрики по изменению покрытия кода, таким образом отслеживается тренд покрытия кода. В качестве референсных метрик используем два ключевых для нас параметра: покрытие строк кода и покрытие условий.
Прогресс не очень быстрый, так как у проекта очень большая база legacy кода — несколько сотен тысяч строк кода. И поэтому за два месяца покрытие увеличилось только на 2 процента. Однако в абсолютных числах количество unit-тестов увеличилось на 25%. Конечно, это не самые впечатляющие цифры, однако главной целью мы ставили изменение подхода команды к написанию unit-тестов и написание интеграционных ddt-тестов. И данная цель нами достигнута!
UI-тестирование
Процесс внедрения ui-тестирования начался с того, что командой было проведено практическое исследование по выбору фреймворка для ui-тестирования. Суть исследования была в том, чтобы выбрать два фреймворка по ui-тестированию и написать на каждом из них несколько ui-тестов. После сравнить результаты и остановится уже на одном. В рамках данного проекта мы выбирали из бесплатных фреймворков Appium и White. По итогу практических испытаний мы остановились на фреймворке White.Процесс был организован следующим образом — на задачи по написанию ui-тестов разработчик выделял 5 часов в неделю. Результаты каждый день отслеживались на стендапе и вносились в специальную таблицу, которая в распечатанном виде находилась возле канбан доски.
На первом этапе были написаны только Smoke ui-тесты (базовые, важнейшие), которые, однако, позволили нам проверить работоспособность готового экземпляра приложения для заказчика в автоматическом режиме, а не вручную, как раньше.
На втором этапе мы внедрили в качестве одного из критериев готовности фичи к тестированию написание ui-теста. Это позволило нам, по мере разработки новых фич, постепенно покрывать весь функционал приложения ui-тестами.
Полностью новой практикой для проекта стало создание тестового экземпляра приложения с включенной аппаратной защитой. Одновременно с этим прошивается тестовый usb-ключ защиты. После чего тестовое приложение инсталлируется на отдельную машину и уже далее ui-тестами тестируется полностью готовое приложение в среде эксплуатации. Это позволило выявлять возможные дефекты на более ранней стадии. Ускорило процесс разработки и сделало его более прозрачным и предсказуемым.
Ведь ранее разработчик, чтобы протестировать приложение с уже работающей системой защиты и всеми компонентами, должен был его предварительно создать, что было достаточно трудоемко и выполнялось только в конце разработки перед передачей на тестирование. Сейчас разработчик может в любой момент времени запустить ui-тестирование на уже готовом приложении, и с учетом минимальной трудоемкости, это стало правилом хорошего тона. Также обязательным правилом стало ui-тестирование перед слиянием в основную ветку разработки.
Релиз-менеджмент
Внедрение Continuous Delivery позволило очень сильно упростить процесс формирования дистрибутивов. Формирование нового экземпляра приложения может быть сделано любым пользователем, а не только разработчиком.Кроме этого автоматизированное тестирование новых экземпляром приложения позволило существенно увеличить производительность команды и дало возможность выпускать релизы в 2 раза чаще.
Технологии
Stack: .NET, C#, C++, Managed C++.Infrastructure: Windows, Jenkins.
Test Automation libraries: Appium, White.
Скриншоты
Особенности проекта
- Наличие системы аппаратной защиты, которая накладывает массу ограничений по тестированию приложения на рабочем месте.
- Сложная система поставки продукта. Формирование индивидуального экземпляра приложения для каждого аппаратного ключа защиты.
- Наукоемкий продукт, очень высокие требования по знаниям в предметной области. Частая ситуация, когда разработчик не знает ожидаемого результата и активно привлекает бизнес-аналитиков и научных сотрудников к процессу разработки.
- Высокая связность legacy кода и как следствие, большая сложность добавления новых функциональностей и трудоемкий рефакторинг.
Результат проекта
После внедрения CI/CD мы достигли следующие результаты:- Постоянно актуальную основную рабочую ветку приложения с работоспособным билдом приложения.
- Существенно уменьшили трудоемкость операций по багфиксингу и поставке новых экземпляров приложений.
- Существенно снизили влияние человеческого фактора с помощью автоматизации поставки и ежедневном автотестировании.
Достижения компании на проекте
- Существенное увеличение скорости разработки.
- Заказчик убедился, что правильная организация процесса тестирования и непрерывной интеграции работает в том числе и на десктопном приложении с аппаратной защитой.
- Полная вовлеченность команды заказчика в написание ui- и unit-тестов.
Свяжитесь с нами, чтобы обсудить Ваш IT-проект