Unit-тести у СУБД — як ми робимо це у Спортмайстрі, частина друга

Перша частина - тут.

Unit-тести у СУБД — як ми робимо це у Спортмайстрі, частина друга

Уявіть ситуацію. Перед вами є завдання розробки нового функціоналу. Ви маєте напрацювання від ваших попередників. Якщо припустити, що ви жодних моральних зобов'язань не маєте, то як би ви вчинили?

Найчастіше всі старі напрацювання забуваються і все починається спочатку. У чужому коді копатися ніхто не любить, а за наявності часу, чому б не зайнятися створенням власної системи? Це типовий підхід, і багато в чому правильний. Але у своєму проекті ми вчинили не так. В основу майбутньої системи автоматичного тестування ми заклали напрацювання з unit-тестів на utPLSQL від попередників, а потім пішли працювати в кількох паралельних напрямках.

  1. Відновлення старих unit-тестів. Під відновленням розуміється адаптація тестів під існуючий стан системи лояльності та адаптація тестів під стандарти utPLSQL.
  2. Вирішення проблеми з розумінням, а що саме, які методи та процеси, у нас покриті автотестами. Треба або цю інформацію пам'ятати, або робити висновки на підставі безпосередньо коду автотестів. Тому ми вирішили сформувати каталог. Кожному автотесту ми надали унікальний мнемокод, сформували опис і зафіксували налаштування (наприклад, в яких умовах він повинен запускатися, або що має відбуватися, якщо запуск тесту завершився невдачею). По суті ми заповнили метадані про автотести і помістили ці метадані в стандартні таблиці схем utPLSQL.
  3. Визначення стратегії розширення, тобто. вибір функціоналу, що підлягає перевірці автотестами. Ми вирішили звернути увагу на три речі: нові доопрацювання системи, інциденти з продакшену та ключові процеси системи. Таким чином, ми розвиваємося паралельно з релізом, забезпечуючи більш високу якість, попутно розширюємо обсяг регресу і забезпечуємо надійність системи в критичних місцях. Першим таким вузьким місцем став процес розподілу знижок та бонусів за чеком.
  4. Звичайно, ми зайнялися розробкою нових автотестів. Однією з перших релізних завдань стала оцінка продуктивності певних вибірок системи лояльності. У нашому проекті є блок жорстко зафіксованих SQL-запитів, які відбирають клієнтів за умовами. Наприклад, отримати список всіх клієнтів, остання купівля яких була в конкретному місті, або список клієнтів, середня сума купівлі яких вища за певне значення. Написавши автотести, ми перевірили певні вибірки, зафіксували еталонні параметри продуктивності, а додатково у нас з'явилися тестування навантаження.
  5. Робота з автотестами має бути зручною. Найчастіше відбуваються дві дії: запуск автотестів та створення тестових даних. Так у нашій системі з'явилися два допоміжні модулі: модуль запуску та модуль генерації даних.

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

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

  6. Автотести повинні запускатися та працювати за прийнятний для вашої системи час. Тому було організовано щоденний нічний запуск, за результатами якого формується звіт про результати та надсилається всій команді розробки по корпоративній пошті. Після відновлення старих автотестів та створення нових загальний час роботи становив 30 хвилин. Подібна продуктивність всіх влаштовувала, оскільки запуск проходив у неробочий час.

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

    Для прискорення продуктивності ми скористалися двома методами: автотести почали запускатися у трьох паралельних потоках, благо це дуже зручно через архітектуру нашої системи лояльності. І ми відмовилися від підходу, коли автотест не створює для себе тестових даних, а намагається знайти в системі щось підходяще. Після внесення змін загальний час роботи скоротився до 3-4 хвилин.

  7. Проект з автотестами треба розгортати на різних стендах. На початку шляху були спроби написати власні батники, але стало зрозуміло, що самописна автоматизована установка - це жах, і ми звернулися в бік промислових рішень. У зв'язку з тим, що в проекті дуже багато безпосередньо коду (насамперед ми зберігаємо код автотестів) і дуже мало даних (основні дані — це метадані про автотести), дуже простим виявилося впровадження в проект Liquibase.

    Це незалежна від бази даних бібліотека з відкритим вихідним кодом для відстеження, керування та застосування змін схеми бази даних. Керується за допомогою командного рядка або фреймворків типу Apache Maven. Принцип роботи Liquibase досить простий. У нас є організований певним чином проект, який складається зі змін чи скриптів, які треба накочувати на цільовий сервер, та керуючі файли, які визначають, у якій послідовності та з якими параметрами дані зміни треба встановлювати.

    На рівні СУБД створюється спеціальна таблиця, де Liquibase зберігає лог накатів. Кожна зміна має розрахований хеш, який щоразу порівнюється між проектом та станом у базі. Завдяки Liquibase ми легко накочуємо зміни нашої системи на будь-який контур. Автотести зараз запускаються на тестовому та релізному контурах, а також на контейнерах (особистих контурах розробників).

Unit-тести у СУБД — як ми робимо це у Спортмайстрі, частина друга

Отже, поговоримо про результати застосування нашої системи unit-тестування.

  1. Звичайно ж, у першу чергу, ми переконані, що почали розробляти якісніше програмне забезпечення. Автотести запускаються щодня та єрелізно знаходять десятки помилок. Причому частина цих помилок лише опосередковано пов'язані з функціоналом, який реально хотіли змінити. Є великі сумніви, що ці помилки знайшли ручним тестуванням.
  2. У команди з'явилася впевненість, що конкретний функціонал працює коректно… Насамперед, це стосується наших критичних процесів. Наприклад, за останні півроку у нас не було проблем із розподілом знижок та бонусів за чеком, незважаючи на єрелізні зміни, хоча в попередні періоди з деякою періодичністю помилки виникали
  3. Нам удалося скоротити кількість ітерацій тестування. Завдяки тому, що автотести пишуться на новий функціонал, до аналітиків та за сумісництвом тестувальникам потрапляє код вищої якості, т.к. його вже було перевірено.
  4. Частина напрацювань автоматизованого тестування використовується розробниками. Наприклад, тестові дані на контейнерах створюються за допомогою модуля створення об'єктів.
  5. Важливо, що ми склалося «прийняття» системи автоматизованого тестування з боку розробників. Є розуміння, що це важливо та корисно. А за своїм досвідом можу сказати, що це не так. Автотести треба писати, їх треба підтримувати та розвивати, аналізувати результати, а часто ці тимчасові витрати просто того не варті. Набагато простіше сходити на продакшн і розбиратися там з проблемами. У нас розробники вишиковуються в чергу і просять покрити їх функціонал автотестами.

Що далі

Unit-тести у СУБД — як ми робимо це у Спортмайстрі, частина друга

Давайте поговоримо про плани розвитку проекту з автоматизованого тестування.

Безумовно, доки система лояльності Спортмайстра жива і продовжує розвиватися, можна також практично нескінченно розвивати автотести. Тому основний напрямок розвитку – це розширення зони покриття.

У міру збільшення кількості автотестів неухильно зростатиме загальний час їх роботи, і нам знову доведеться повернутися до питання продуктивності. Швидше за все, рішення буде збільшення кількості паралельних потоків.

Але це очевидні шляхи розвитку. Якщо говорити про щось більш нетривіальне, виділимо таке:

  1. Нині управління автотестами виконується лише на рівні СУБД, тобто. необхідні знання PL/SQL для успішної роботи. За необхідністю управління системою (наприклад, здійснення запусків або створення метаданих) можна винести якусь адмінку, використовуючи Jenkins або щось аналогічне.
  2. Усі люблять кількісні та якісні показники. Для автоматичного тестування таким універсальним показником є ​​Code Coverage або метрика покриття коду. За допомогою цього показника ми можемо визначити, який відсоток коду нашої системи покривається автотестами. Починаючи з версії 12.2, Oracle надає можливості з розрахунку даної метрики і пропонує використовувати стандартний пакет DBMS_PLSQL_CODE_COVERAGE.

    Нашій системі автотестування трохи більше року і, можливо, зараз час для оцінки покриття. У моєму минулому проекті (проект не Спортмайстра) так і вийшло. Через рік після роботи над автотестами керівництво поставило завдання оцінити, який відсоток коду ми покриваємо. При покритті понад 1% керівництво було б щасливим. Ми, розробники, очікували на результат близько 10%. Прикрутили code coverage, виміряли, отримали 20%. На радостях вирушили за премією, але як ми за нею сходили і куди попрямували згодом, це зовсім інша історія.

  3. Автотести можуть перевіряти виставлені веб-сервіси. Oracle цілком дозволяє це робити, а ми більше не зустрінемо цілу низку проблем.
  4. І, звичайно, нашу систему автоматизованого тестування можна застосувати на іншому проекті. Отримане нами рішення є універсальним і лише вимагає використання Oracle. Я чув, що на інших проектах Спортмайстра є зацікавленість в автоматичному тестуванні і, можливо, ми вирушимо до них.

Висновки

Давайте підсумуємо. На проекті система лояльності у Спортмайстрі нам удалося реалізувати систему автоматизованого тестування. Базисом її є рішення utPLSQL від Стівена Фейєрштейна. Навколо utPLSQL розташований код автотестів та допоміжні самописні модулі: модуль запуску, модуль генерації даних та інші. Автотести щодня запускаються і, що найважливіше, працюють та приносять користь. Ми переконані, що почали випускати програмне забезпечення вищої якості. При цьому отримане рішення є універсальним і може бути вільно застосовано на будь-якому проекті, де необхідно організувати автоматизоване тестування на СУБД Оракл.

PS Ця стаття вийшла не дуже конкретною: тут багато тексту та практично відсутні технічні приклади. Якщо глобально тематика цікава, то ми готові її продовжити і повернутися з продовженням, де розповімо, що змінилося за півроку і навести приклади коду.

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

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Пишемо далі про таке?

  • Так звісно

  • Ні дякую

Проголосували 12 користувачів. Утрималися 4 користувача.

Джерело: habr.com

Додати коментар або відгук