Інфраструктура та пайплайн (CI/CD)

У цій темі у мене мало досвіду, імовірність біліберди збільшена втричі.

Наразі компетентність у сфері 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 плагінів для інтеграції зі сторонніми платформами, для розширення інтерфейсу користувача, адміністрування, управління вихідним кодом і збіркою.

Багато команд, що використовують CI/CD-конвеєри у хмарах використовують контейнери , такі як Docker , та системи оркестрації , такі як Kubernetes. Контейнери дозволяють стандартизувати упаковку, постачання та спростити масштабування та знищення оточення з непостійним навантаженням. Є безліч варіантів спільного використання контейнерів, інфраструктури як код ( Iaas) та CI/CD-конвеєрів. Архітектура безсерверних обчислень є ще одним способом розгортання і масштабування додатків. У безсерверному оточенні інфраструктурою повністю керує постачальник хмарних послуг, а програма споживає ресурси за необхідності відповідно до його налаштувань. Наприклад, в AWS безсерверні програми запускаються через функції AWS Lambda, розгортання яких може бути інтегровано в CI/CD-конвеєр Jenkins за допомогою плагіна.

Більше про CI/CD можна почитати тут і тут .

Етапи конвеєра

У момент, коли тригериться складання, наприклад, коли розробник зробив комміт у свою гілку, запускається процес, який виконується спеціально написаними скриптами та утилітами. Цей процес складається з кількох обов'язкових кроків. Простий приклад для PR:

  • При відкритті кожного Pull Request Git-сервер відправляє повідомлення CI-серверу;

  • CI-сервер клонує репозиторій, перевіряє вихідну гілку (наприклад bugfix/wrong-sorting), та зливає код з кодом master-гілки;

  • Тоді запускається білд-скрипт (сценарій збирання). Наприклад ./gradlew build;

  • Якщо команда повертає код відповіді “0”, то білд успішно виконано. (Інша відповідь означає помилку);

  • CI-сервер надсилає повідомлення про успішний білд на Git-сервері;

  • Якщо білд був успішний, Pull Request дозволяється злити з існуючим кодом. (Якщо не успішний, то, відповідно, не дозволяється).

Помилка в будь-якому з кроків призводить до повного падіння всієї збірки. Ну і, зрозуміло, кроки розташовані в такому порядку, щоб звужувати вирву потенційних проблем. Якщо Quality Gate попереднього етапу не пройде, то на перевірку наступного можна не витрачати ресурси.

Приклад Quality Gates, які вбудовані в pipeline звідси :

  • Складання сервісу:

    • Перевірка конфігурації коректного формату;

    • Перевірка стандартів оформлення коду;

    • Перевірка на потрібне покриття 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 перед злиттям, а також призначатися групи осіб, які вимагають схвалення перед злиттям.

Більше про build-agent можна почитати тут: TeamCity : налаштовуємо CI/CD у вашій команді і тут Що таке збирач продукту , про оточення тут

Е2Е автотести

Тепер настав час поговорити безпосередньо про те, що найчастіше стосується рядового автоматизатора - Е2Е автотести . Як ми з'ясували вище, до прогону Е2Е складання спочатку проходить кілька кроків, а умовами запуску найчастіше є ключові моменти: commit, pull request та merge request. У моїй минулій компанії був дуже простий конвеєр, де на комміт у фічу-гілку запускалися тести розробника, на вливання в develop стартували критичні Е2Е тести, а на вливання в main вже все що є, включаючи регресійні тести. Тепер, коли відомі місця автотестів у конвеєрі, потрібно ще зрозуміти, на чому ці тести проганятимуться і як маючи скрипт автотесту його запустити в конвеєрі.

Всі ці моменти конфігуруються у самому CI-агенті, у jenkins це були джоби (job). Приклад: How to Add your First Android Job to Jenkins . За запуск коду тестів, коли ви ініціюєте запуск із конвеєра або локально, відповідає Test Runner . Це лише одне із завдань, в зону відповідальності раннера входять :

  • підготовка оточення;

  • формування набору тестів для виконання;

  • запуск тестів;

  • одержання результатів виконання тестів;

  • підготовка звітів про проходження тестів;

  • збирання статистики.

Незважаючи на те, що з фреймворком поставляється і раннер, існує можливість використання більш досконалих сторонніх раннерів.

Паралельно з питанням про те, який раннер вибрати для тестів, перед вами постає інший: а на чому краще запускати тести? Є три опції:

  • Справжній девайс.

    • Плюси. Покаже проблеми, специфічні для конкретних пристроїв та прошивок. Багато виробників змінюють Android під себе – як UI, так і логіку роботи ОС. І буває корисно перевірити, що ваша програма коректно працює в такому оточенні.

    • Мінуси. Необхідно десь видобути ферму пристроїв, організувати спеціальне приміщення під них – необхідна низька температура, небажано попадання прямих сонячних променів тощо. д. Крім того, акумулятори мають властивість здуватися та виходити з ладу. А ще самі тести можуть змінювати стан пристрою, і ви не можете просто взяти та відкотитися на якийсь стабільний снепшот.

  • Чистий емулятор. Під "чистим" ми маємо на увазі, що ви запускаєте емулятор у себе або десь на машині, використовуючи встановлений на цю машину AVD Manager.

    • Плюси. Швидше, зручніше і стабільніше за цей пристрій. Створення нового емулятора займає кілька хвилин. Жодних проблем з окремим приміщенням, акумуляторами та іншим.

    • Мінуси. Відсутність згаданих вище device specifics. Однак часто кількість тестових сценаріїв, зав'язаних на специфіку пристрою, мізерно мала, і вони не є пріоритетними. Але найголовніший мінус - це погана масштабованість. Просте завдання залити нову версію емулятора на всі хости перетворюється на муку.

  • Docker-образ Android-емулятора. Docker вирішує недоліки чистих емуляторів.

    • Плюси. Docker і відповідна обв'язка у вигляді підготовки і розкочування образу емулятора - це повноцінне рішення, що масштабується, що дозволяє швидко і якісно готувати емулятори і розкачувати їх на всі хости, забезпечуючи їх достатню ізольованість.

    • Мінуси. Вищий вхідний поріг.

У мережі є різні Docker-образи Android-емуляторів:

Має зробити складний вибір між хмарним рішенням, локальним рішенням з нуля і локальним рішенням на базі чогось, якщо в компанії є своя інфраструктура із запуску тестів інших платформ. Вся ця інфраструктура вже пов'язується з раннером для запуску тестів, після чого вже вирішуються інші моменти, такі як виведення звіту про прогону тестів (наприклад, Allure) та впровадження/синхронізація з TMS.

Джерела:

Дод. матеріал:

Last updated