Інфраструктура та пайплайн (CI/CD)
Last updated
Last updated
У цій темі у мене мало досвіду, імовірність біліберди збільшена втричі.
Наразі компетентність у сфері TestOps є такою самою базовою вимогою до QA-інженерів, як і написання автоматизованих тестів. Причина - в активному розвитку CI/CD у проектах та необхідності QA-інженерам працювати з пайплайнами
Багато автоматизаторів-початківців кидаються вивчати мову програмування, пишуть перші навчальні тести і навіть успішно роблять тестові завдання з автоматизації тест-кейсів. Однак не всі замислюються над тим, що з цими тестами в реальній роботі робити далі. Хто їх запускатиме? Коли? Яким чином? Тут я б хотів розповісти про пайплайн CI, місце автотестів у ньому, а так само як і на чому тести запускаються.
Насамперед, звідки цей пайплайн взявся і що за CI/CD.
Безперервна інтеграція (Continuous Integration, CI) і безперервне постачання (Continuous Delivery, CD) є культурою, набором принципів і практик, які дозволяють розробникам частіше і надійніше розгортати зміни програмного забезпечення.
CI/CD – це одна з DevOps-практик. Вона також відноситься і до agile-практиків: автоматизація розгортання дозволяє розробникам зосередитися на реалізації бізнес-вимог, якості коду та безпеки.
Безперервна інтеграція - це методологія розробки та набір практик, за яких код вносяться невеликі зміни з частими комитами. І оскільки більшість сучасних додатків розробляються з використанням різних платформ та інструментів, то виникає потреба в механізмі інтеграції та тестуванні змін, що вносяться. З технічної точки зору, мета CI - забезпечити послідовний та автоматизований спосіб складання, пакування та тестування додатків. При налагодженому процесі безперервної інтеграції розробники з більшою ймовірністю робитимуть часті комміти, що, у свою чергу, сприятиме покращенню комунікації та підвищенню якості програмного забезпечення.
Безперервне постачання починається там, де закінчується безперервна інтеграція. Вона автоматизує розгортання додатків у різні оточення : більшість розробників працюють як з продакшн-оточенням, так і з середовищами розробки та тестування.
Інструменти CI/CD допомагають налаштовувати специфічні параметри оточення, які конфігуруються під час розгортання. А також CI/CD-автоматизація виконує необхідні запити до веб-серверів, баз даних та інших сервісів, які можуть потребувати перезапуску або виконання якихось додаткових дій під час розгортання програми.
Безперервна інтеграція та безперервне постачання потребують безперервного тестування, оскільки кінцева мета – розробка якісних додатків. Безперервне тестування часто реалізується у вигляді набору різних автоматизованих тестів (регресійних, продуктивності та інших), які виконуються в CI/CD-конвеєрі (pipeline, build chain тощо). Зріла практика CI/CD дозволяє реалізувати безперервне розгортання: при успішному проходженні коду через CI/CD-конвеєр, збірки автоматично розгортаються у продакшн-оточенні. Команди, які практикують безперервне постачання, можуть дозволити собі щоденне або навіть щогодинне розгортання.
Типовий CD- конвеєр складається з етапів складання, тестування та розгортання. Більш складні конвеєри включають наступні етапи:
Отримання коду із системи контролю версій та виконання складання;
Налаштування інфраструктури, автоматизованої через підхід “інфраструктура як код”;
Копіювання коду у цільове середовище;
Налаштування оточення для цільового середовища;
Розгортання компонентів програми (веб-сервери, API-сервіси, бази даних);
виконання додаткових дій, таких як перезапуск сервісів або виклик сервісів, необхідних для працездатності нових змін;
Виконання тестів та відкат змін оточення у разі провалу тестів;
Логування та надсилання сповіщень про стан поставки.
Наприклад, у Jenkins конвеєр визначається у файлі Jenkinsfile, в якому описуються різні етапи, такі як складання (build), тестування (test) та розгортання (deploy). Там же описуються змінні оточення, секретні ключі, сертифікати та інші параметри, які можна використовувати на етапах конвеєра. У розділі post налаштовується обробка помилок та сповіщення. У складнішому CD-конвеєрі можуть бути додаткові етапи, такі як синхронізація даних, архівування інформаційних ресурсів, встановлення оновлень та патчів. CI/CD-інструменти зазвичай підтримують плагіни. Наприклад, у Jenkins є більше 1500 плагінів для інтеграції зі сторонніми платформами, для розширення інтерфейсу користувача, адміністрування, управління вихідним кодом і збіркою.
Етапи конвеєра
У момент, коли тригериться складання, наприклад, коли розробник зробив комміт у свою гілку, запускається процес, який виконується спеціально написаними скриптами та утилітами. Цей процес складається з кількох обов'язкових кроків. Простий приклад для PR:
При відкритті кожного Pull Request Git-сервер відправляє повідомлення CI-серверу;
CI-сервер клонує репозиторій, перевіряє вихідну гілку (наприклад bugfix/wrong-sorting), та зливає код з кодом master-гілки;
Тоді запускається білд-скрипт (сценарій збирання). Наприклад ./gradlew build;
Якщо команда повертає код відповіді “0”, то білд успішно виконано. (Інша відповідь означає помилку);
CI-сервер надсилає повідомлення про успішний білд на Git-сервері;
Якщо білд був успішний, Pull Request дозволяється злити з існуючим кодом. (Якщо не успішний, то, відповідно, не дозволяється).
Помилка в будь-якому з кроків призводить до повного падіння всієї збірки. Ну і, зрозуміло, кроки розташовані в такому порядку, щоб звужувати вирву потенційних проблем. Якщо Quality Gate попереднього етапу не пройде, то на перевірку наступного можна не витрачати ресурси.
Складання сервісу:
Перевірка конфігурації коректного формату;
Перевірка стандартів оформлення коду;
Перевірка на потрібне покриття Unit-тестами;
Генерації та публікації контрактів (контроль зворотної сумісності).
Запуск Beta-тестів;
Обов'язковий code-review;
Сканування на вразливість.
Code scanning: код перевіряється на відповідність загальному гайдлайну (linters), вразливості (code security) та якість (code quality);
Unit tests;
Build: етап для складання artifacts/packages/images і т.д. Тут вже можна задуматися про те, якою буде стратегія версіонування всього додатку. За часів контейнеризації в першу чергу цікавлять образи для контейнерів та способи їх версіонування;
Scan package: пакет/образ зібрали. Тепер потрібно просканувати його на вразливості. Сучасні registre вже містять інструментарій для цього;
Deploy: стадія для розгортання програми у різних оточеннях;
Integration testing: програму задеплоїли. Воно десь мешкає в окремому контурі. Настає етап інтеграційного тестування. Тестування може бути як ручним, і автоматизованим;
Performance testing (load/stress testing): даний вид тестування має сенс проводити на stage/pre-production оточення. З тією умовою, що ресурсні потужності на ньому такі ж, як у production;
Code Review / Approved: одним із найважливіших етапів є Merge Request. Саме в них можуть проводитися окремі дії в pipeline перед злиттям, а також призначатися групи осіб, які вимагають схвалення перед злиттям.
Е2Е автотести
Тепер настав час поговорити безпосередньо про те, що найчастіше стосується рядового автоматизатора - Е2Е автотести . Як ми з'ясували вище, до прогону Е2Е складання спочатку проходить кілька кроків, а умовами запуску найчастіше є ключові моменти: commit, pull request та merge request. У моїй минулій компанії був дуже простий конвеєр, де на комміт у фічу-гілку запускалися тести розробника, на вливання в develop стартували критичні Е2Е тести, а на вливання в main вже все що є, включаючи регресійні тести. Тепер, коли відомі місця автотестів у конвеєрі, потрібно ще зрозуміти, на чому ці тести проганятимуться і як маючи скрипт автотесту його запустити в конвеєрі.
підготовка оточення;
формування набору тестів для виконання;
запуск тестів;
одержання результатів виконання тестів;
підготовка звітів про проходження тестів;
збирання статистики.
Незважаючи на те, що з фреймворком поставляється і раннер, існує можливість використання більш досконалих сторонніх раннерів.
Паралельно з питанням про те, який раннер вибрати для тестів, перед вами постає інший: а на чому краще запускати тести? Є три опції:
Справжній девайс.
Плюси. Покаже проблеми, специфічні для конкретних пристроїв та прошивок. Багато виробників змінюють Android під себе – як UI, так і логіку роботи ОС. І буває корисно перевірити, що ваша програма коректно працює в такому оточенні.
Мінуси. Необхідно десь видобути ферму пристроїв, організувати спеціальне приміщення під них – необхідна низька температура, небажано попадання прямих сонячних променів тощо. д. Крім того, акумулятори мають властивість здуватися та виходити з ладу. А ще самі тести можуть змінювати стан пристрою, і ви не можете просто взяти та відкотитися на якийсь стабільний снепшот.
Чистий емулятор. Під "чистим" ми маємо на увазі, що ви запускаєте емулятор у себе або десь на машині, використовуючи встановлений на цю машину AVD Manager.
Плюси. Швидше, зручніше і стабільніше за цей пристрій. Створення нового емулятора займає кілька хвилин. Жодних проблем з окремим приміщенням, акумуляторами та іншим.
Мінуси. Відсутність згаданих вище device specifics. Однак часто кількість тестових сценаріїв, зав'язаних на специфіку пристрою, мізерно мала, і вони не є пріоритетними. Але найголовніший мінус - це погана масштабованість. Просте завдання залити нову версію емулятора на всі хости перетворюється на муку.
Docker-образ Android-емулятора. Docker вирішує недоліки чистих емуляторів.
Плюси. Docker і відповідна обв'язка у вигляді підготовки і розкочування образу емулятора - це повноцінне рішення, що масштабується, що дозволяє швидко і якісно готувати емулятори і розкачувати їх на всі хости, забезпечуючи їх достатню ізольованість.
Мінуси. Вищий вхідний поріг.
У мережі є різні Docker-образи Android-емуляторів:
Має зробити складний вибір між хмарним рішенням, локальним рішенням з нуля і локальним рішенням на базі чогось, якщо в компанії є своя інфраструктура із запуску тестів інших платформ. Вся ця інфраструктура вже пов'язується з раннером для запуску тестів, після чого вже вирішуються інші моменти, такі як виведення звіту про прогону тестів (наприклад, Allure) та впровадження/синхронізація з TMS.
Джерела:
Дод. матеріал:
Багато команд, що використовують CI/CD-конвеєри у хмарах використовують контейнери , такі як , та системи оркестрації , такі як Kubernetes. Контейнери дозволяють стандартизувати упаковку, постачання та спростити масштабування та знищення оточення з непостійним навантаженням. Є безліч варіантів спільного використання контейнерів, інфраструктури як код ( Iaas) та CI/CD-конвеєрів. Архітектура безсерверних обчислень є ще одним способом розгортання і масштабування додатків. У безсерверному оточенні інфраструктурою повністю керує постачальник хмарних послуг, а програма споживає ресурси за необхідності відповідно до його налаштувань. Наприклад, в AWS безсерверні програми запускаються через функції AWS Lambda, розгортання яких може бути інтегровано в CI/CD-конвеєр Jenkins за допомогою плагіна.
Більше про CI/CD можна почитати і .
Приклад Quality Gates, які вбудовані в pipeline :
Приклад сферичного пайплайну у вакуумі :
Більше про build-agent можна почитати тут: і тут , про оточення тут
Всі ці моменти конфігуруються у самому CI-агенті, у jenkins це були джоби (job). Приклад: . За запуск коду тестів, коли ви ініціюєте запуск із конвеєра або локально, відповідає Test Runner . Це лише одне із завдань, в зону відповідальності раннера :
;
;
.
, ,