Найкращі способи протестувати свої безсерверні програми

Безсерверність - це більше, ніж модель виконання хмарних обчислень. Це змінює спосіб планування, створення та розгортання програм. Але це також змінює спосіб тестування наших додатків.

Зустріньте Алекса. Алекс - звичайний розробник JavaScript, останнім часом зосереджений на Node.js.

Протягом останніх кількох місяців його хороші друзі, Анна та Джефф, завжди говорять про цю безсерверну штучку. Навіть через те, що вони час від часу дратують, йому подобається ідея безсерверних додатків. Він навіть застосував кілька простих функцій до AWS Lambda та Azure.

У якийсь момент Алекс та його команда отримали новий проект. Провівши певний аналіз, Алекс подумав, що він ідеально підходить для безсерверних. Він представив ідею своїй команді. Деякі учасники команди були схвильовані, одному з них це не сподобалось, але більшість з них не мали твердої думки. Тож вони вирішили спробувати - проект не був надто великим, і ризик був низьким.

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

На той момент їхній процес виглядає так:

  1. Вони аналізують нову функцію.
  2. Для менш складних функцій вони починають з коду, потім запускають його локально і в кінці додають деякі тести.
  3. Для більш складних функцій вони роблять свою версію TDD: вони починають з тестів, потім пишуть код і тестують його локально.
  4. Коли функція готова, вона переходить до інструмента CI, який розгортає її до середовища тестування.
  5. Тоді команда QA приймає нову функцію для чергового раунду тестування вручну. Якщо все виглядає добре, програма переходить через CI до виробництва.

Вони вирішили почати крок за кроком, а потім вирішувати проблеми, коли стикалися з ними.

Вони вибрали невелику функцію, і як це було просто, вони почали з коду. Коли частина кодування була готова, вони вдарили перший блокпост: як локально запускати безсерверні програми?

Місцеве тестування

З безсерверними програмами ви не керуєте інфраструктурою. Звучить чудово, але як тоді запустити програму локально? Ви навіть можете це зробити?

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

  • Основні інструменти функцій Azure (для функцій Azure)
  • CLI AWS SAM (для програм AWS Lambda, побудованих за допомогою AWS SAM)
  • Сторонні інструменти (тобто. Localstack)
  • docker-lambda для локального моделювання AWS Lambda
  • Запустіть функцію Node.js локально

Звичайно, список не повний - інструментів більше, і ми бачимо нові інструменти майже щодня.

Більшість цих інструментів мають певні обмеження. Вони можуть імітувати безсерверні функції та кілька інших служб, таких як API Gateway. Але як щодо дозволів, рівня авторизації та інших служб?

Місцеве тестування допомагає швидко перевірити, щоб переконатися, що ваша функція працює. Але чи є кращий спосіб переконатися, що ваш безсерверний додаток працює належним чином? Так є. Перший і найважливіший крок - це написати тести.

Тож Олексій та його команда спробували свою першу функцію на місцевому рівні, і, здавалося, це спрацювало. Потім вони перейшли до наступного кроку.

Автоматизовані тести

Алекс та його команда щойно перейшли на Jest для тестування своїх програм Node.js. Вони все ще роблять багато інтерфейсу, тому вони хочуть використовувати ті самі інструменти для повного стеку, коли тільки можуть. Чи можуть вони також використовувати Jest для тестування безсерверних додатків? І що вони повинні перевірити?

Після швидкого дослідження вони зрозуміли, що можуть використовувати свої улюблені засоби тестування Node.js. Jest, Jasmine, Mocha та інші чудово працюють з безсерверними.

Що слід протестувати в безсерверному додатку?

За допомогою своїх програм Node.js Алекс та його команда дотримуються трирівневої піраміди автоматизації тестів. Вперше про випробувальну піраміду згадав Майк Кон у своїй книзі “Успіх з Agile”.

Як визначає тестова піраміда, вони мають:

  • Багато модульних тестів, оскільки вони найдешевші (найшвидші для написання та запуску)
  • Менше інтеграційних тестів, оскільки вони дорожчі, і на їх виконання потрібно більше часу
  • Кілька тестів інтерфейсу користувача, оскільки вони є найдорожчими (потрібен певний інструмент графічного інтерфейсу) та найповільнішими для запуску

Окрім цього, вони також проводять ручне тестування на основі сесій, проведене їх командою контролю якості.

Як безсерверний вплив на піраміду автоматизації тестів?

Відповідь залежить від рівня. Але тестова піраміда менш схожа на єгипетські піраміди, а більше на піраміди майя.

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

Рівень тестування інтеграції стає важливим як ніколи раніше, оскільки безсерверні програми значною мірою покладаються на інтеграції. Це також дешевше, оскільки наявність безсерверної бази даних лише для тестування дешева. Отже, у безсерверній «тестовій піраміді» потрібно мати більше тестів інтеграції.

Тестовий рівень графічного інтерфейсу також дешевший і швидший через дешевше розпаралелювання.

Ручний рівень тестування залишається незмінним. Але безсерверний може допомогти вам трохи його вдосконалити. Детальніше про це ми поговоримо пізніше.

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

Як написати тестовані безсерверні функції

Під час написання безсерверної функції потрібно подумати про такі ризики:

  • Ризики конфігурації Чи правильна база даних і таблиця? Або у вас є права доступу?
  • Технічні ризики робочого процесуВи аналізуєте та використовуєте вхідний запит як слід? Або ви правильно обробляєте вдалі відповіді та помилки?
  • Ризики бізнес-логікиВи дотримувались усіх правил ділової логіки, які має ваша програма?
  • Ризики інтеграції Чи правильно ви читаєте структуру вхідного запиту? Або ви правильно зберігаєте замовлення в базі даних?

Щоб підтвердити, що ваша безсерверна функція працює правильно, вам потрібно перевірити всі ці ризики.

Ви можете протестувати кожен із них, як і для інтеграційних тестів. Але налаштування та налаштування служби кожного разу, коли ви хочете перевірити на один із цих ризиків, не є оптимальним. Як любить говорити мій друг Олександр Симович:

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

Щоб зробити додаток більш перевіреним, явним рішенням є розбиття вашої функції на кілька менших.

Одним з чудових способів зробити це застосування шестикутної архітектуридо ваших безсерверних функцій.

Гексагональна архітектура, або порти та адаптери , є формою архітектури додатків, яка сприяє розділенню проблем через рівні відповідальності. Як пояснює його творець Алістер Кокберн:

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

Отже, як це стосується безсерверних функцій?

Оскільки Алекс та його команда використовують AWS, вони отримали таку структуру:

  • Функція бізнес-логіки надає мало «портів» (або передбачає мало аргументів). Наприклад, один для вхідної події, один для постійного зберігання та один для сповіщень.
  • У них є два адаптери для події, яка запускає функцію, один для справжнього лямбда-тригера AWS та інший для локального тестування.
  • Вони мають кілька адаптерів для постійного зберігання та сповіщень. Наприклад, адаптер таблиці DynamoDB та адаптер пам'яті.

Олексій та його команда були щасливі, що вони рухаються вперед. Але перш ніж рухатись далі, давайте подивимося, як шестикутна архітектура впливає на кожен рівень тестової піраміди.

Блокове тестування

Блокові тести залишились колишніми. Але простіше писати модульні тести через Гексагональну архітектуру. Вони можуть просто використовувати локальний адаптер або макет як адаптер для ізольованого тестування функціонального рівня бізнесу.

Інтеграційне тестування

Інтеграційні тести отримали велику користь від Гексагональної архітектури. Вони змогли повністю перевірити власні інтеграції. Інтеграція сторонніх розробників моделюється за допомогою інших адаптерів.

Як це працює на практиці?

Кожні з їх функцій бессерверной мають lambda.js і main.js файли. Основний файл містить бізнес-логіку безсерверної функції. А файл lambda.js відповідає за підключення адаптерів та виклик файлу main.js.

Основний файл має власні модульні та інтеграційні тести. Але його інтеграційні тести не перевіряють повної інтеграції з кінцевими службами, такими як AWS S3, оскільки це може сповільнити їх роботу. Натомість вони використовують адаптер в пам’яті для тестування функції з інтеграцією сховища файлів.

Інтеграція AWS S3 здійснюється через FileRepository , який має власні модульні та інтеграційні тести. Перевірки інтеграційних тестів використовують AWS S3, щоб переконатися, що кінцева інтеграція насправді працює.

На відміну від main.js , файл lambda.js не має тестів, оскільки більшу частину часу він має лише кілька рядків коду.

Цей підхід схожий на техніку, яку команда MindMup використовує для тестування безсерверних функцій. За допомогою нього ви можете легко протестувати інтеграцію своїх функцій і при цьому зробити свої тести інтеграції швидшими.

Тестування графічного інтерфейсу

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

Тести користувальницького інтерфейсу є дорогими і повільними, оскільки вони працюють у браузері. Але безсерверний - це дешево, і він швидко масштабується.

Якби вони могли запустити браузер в AWS Lambda, вони отримали б дешеве розпаралелювання. Це зробило б їх тести інтерфейсу дешевшими та швидшими.

Але чи можете ви запустити браузер, такий як Chrome, всередині безсерверної функції?

Так! І це легко за допомогою таких інструментів, як безсерверний Chrome, Chromeless та Puppeteer.

Поєднання безсерверного та безголового браузерів може запропонувати нам нове покоління засобів тестування інтерфейсу. Ми вже можемо побачити і спробувати деякі з них, наприклад, «Оцінити».

CI / CD

Коли Алекс та його команда тестували свою першу безсерверну функцію, настав час розгорнути код у середовищі тестування. Це породило нове запитання: як вони можуть використовувати інструменти CI / CD для розгортання своєї безсерверної програми?

Відповідь проста: вони можуть використовувати інструмент CI для запуску тестів та розгортання програми. Для розгортання програми використовуйте будь-який популярний інструмент, такий як Claudia.js, AWS SAM та Serverless Framework.

Ви все ще можете використовувати свій улюблений інструмент CI (наприклад, Jenkins, TravisCI або SemaphoreCI), або якщо ви хочете дотримуватися AWS, ви можете спробувати AWS CodeBuild.

Тестування вручну

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

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

Це означає, що тестування середовища ніколи не було дешевшим!

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

Крім тестування

Алекс та його команда передали свою першу безсерверну функцію до попереднього виробництва, і команда була щаслива, що вони навчились тестувати безсерверні програми.

Вони продовжували використовувати безсерверний проект і вводити його в кілька інших проектів. Алекс приєднався до своїх друзів Анни та Джеффа, як третій, часом надокучливий, безсерверний проповідник. І жили вони довго та щасливо.

Пост-сценарій

Але навіть незважаючи на те, що їх додаток був добре протестований, щось трапилось за одну ніч.

Після розслідування вони виявили, що одна з інтеграцій змінилася. Вони зрозуміли, що тестування є важливим для безсерверних додатків, але цього недостатньо.

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

На щастя, щодня на ринку з’являється все більше безсерверних інструментів моніторингу. Деякі хороші та популярні варіанти - IOpipe, Thundra, Dashbird та Epsagon.

Але у безсерверних додатків часто є товстий клієнт, а це означає, що моніторингу на задній панелі недостатньо. Вам потрібен подібний інструмент для вашого переднього кінця. На цьому ринку також є багато приємних інструментів, таких як Sentry та Rollbar.

Але в дусі безсерверності ми створили програму відстеження помилок з відкритим кодом під назвою Desole. Це безсерверний додаток, який ви можете встановити у своєму обліковому записі AWS. Це дозволяє організаціям відстежувати винятки та помилки програм, не вибираючи між зручністю програмного забезпечення як послуги та безпекою самостійного рішення. Ви можете перевірити це тут: //desole.io.

Усі ілюстрації створені за допомогою програми SimpleDiagrams4.

Якщо ви хочете дізнатись більше про тестування та створення безсерверних додатків за допомогою Node.js та AWS, перегляньте “Безсерверні програми з Node.js”, книгу, яку я написав з Олександром Сімовичем для Manning Publications:

Безсерверні програми з Node.js

Переконливий вступ до безсерверних розгортань за допомогою Claudia.js. www.manning.com

Книга навчить вас більше про безсерверне тестування з прикладами коду, але ви також дізнаєтесь, як створити та налагодити безсерверний API реального світу (з БД та автентифікацією) за допомогою Node та Claudia.js. І ви дізнаєтесь, як створювати чат-боти, для Facebook Messenger та SMS (за допомогою Twilio) та навички Alexa.