Тестування клієнта REST на сервері REST. Як робити світильники?


10

При написанні одиничних тестів звичайно використовувати світильники: мало перевіряються даних, тому ми можемо сказати: 1. Отримати всіх клієнтів слід, зокрема, Віллі Вонка. 2. Видаліть клієнт 3, і тепер клієнти більше не повинні включати Віллі Вонка.

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

А як бути, коли ми відокремили сервер REST від клієнта REST?

Ми хочемо переконатися, що наш REST-клієнт не просто читає правильно, а створює, оновлює та видаляє правильно.

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

Припустимо, що у мене є тестовий сервер REST, який обслуговує лише світильники. Увесь HTTP-статус без громадянства означає, що важко буде надіслати повідомлення типу "НАЧАЛЬНА ПЕРЕВІРКА" та "ПОВЕРНЕННЯ ПЕРЕВ'ЯЗКУ" або "ЗВ'ЯЗКУВАННЯ ФІКСТУРІВ", правда?

Я не можу бути першим, хто захотів це зробити, тому у мене є відчуття, що мені потрібен інший спосіб думати про це.

Будь-які пропозиції?


Можливо, оскільки це тестовий сервер, ви можете мати кінцеву точку, яка буде перезавантажувати світильники?
Девід Редкліфф

Якщо ваша основна проблема полягає в тому, щоб повернути тестовий сервер у заздалегідь заданий стан, чому б вам не додати в свій решта API такі спеціальні функції тестування, як "RELOAD TESTDATA", щоб робити те, що ви хочете? Звичайно, ви повинні переконатися, що такі виклики API недоступні у виробництві.
Док Браун

Відповіді:


7

Програмні системи в ідеалі мають чітко визначені межі системи та інтерфейси між ними. Служби REST - хороші приклади цього.

З цією метою я б рекомендував не робити те, що ви намагаєтеся зробити.

Конкретно:

Ми хочемо переконатися, що наш REST-клієнт не просто читає правильно, а створює, оновлює та видаляє правильно.

Я б замість цього запропонував:

  • Створення тестів для вашого REST-клієнта, щоб переконатися, що він поводиться правильно, враховуючи конкретний вхід та вихід. Облік хороших (очікуваних) та поганих (несподіваних) значень.

  • Створення тестів для вашої служби REST (якщо ви керуєте нею, тобто), щоб вона вела себе відповідно до її призначеної функції

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


3
Ви відкидаєте всю ідею інтеграційних тестів тут досить випадково. Я не вважаю, що такий підхід відомий з практики.
підступність

Дякую за всі корисні пропозиції. Також у Twitter я отримав чудові пропозиції спробувати Ruby gem "webmock" і подібне, щоб знущатися з відповіді сервера REST API. Я також погоджуюся з "підступністю", що те, що я описую, здається, є більш інтеграційним тестом, тому я розгляну це окремо. Ще раз дякую всім. - Дерек
Сіверс

глузування з API - це відмінний спосіб вирішити проблему. Але як ви переконаєтесь, що насмішкували API == справжній API?
FrEaKmAn

4

Тут слід пам’ятати два кути:

  • Ви протестуєте свій код або сантехніку? Якщо припустити, що ви використовуєте добре відомий сервіс та клієнтський стек, ви, ймовірно, можете сміливо припускати їх тестерів, а тисячі користувачів, як правило, гарантують, що в підмурках немає фундаментальної помилки.
  • Чому ваші тести не мають сили? Створіть спосіб запису невиробничих даних або запишіть до іншої кінцевої точки. Виберіть деяку передбачувану схему іменування. Попередньо завантажте БД сервера відпочинку перед тестами. І, мабуть, є ще кілька способів зробити це - метод дійсно тактичний і повинен залежати від характеру програми.

2

Я думаю, що підробка відповідей сервера REST - це найкращий спосіб перевірити клієнта.

Для Ruby є дорогоцінний камінь FakeWeb, який можна використовувати для надсилання підроблених відповідей - https://github.com/chrisk/fakeweb .

Також у JavaScript ви можете використовувати щось на кшталт Sinon.JS, що дає вам підроблений сервер - http://sinonjs.org/docs/#fakeServer .


1

Як говорили інші, якщо ви тестуєте клієнта, вам не потрібно йти так далеко, як створювати, видаляти тощо на сервері. Багато часу вам навіть не потрібно знущатися над сервером. Вам дійсно потрібно лише переконатися, що ви робите правильні запити та правильно обробляєте відповіді, будь то написано на Ruby, Python, PHP чи щось інше, але в якийсь момент ваш клієнт, ймовірно, буде використовувати метод з бібліотеки HTTP, щоб зробити запит, і досить знущатися над цим методом, перевіряти, як він викликається, і повертати результат тесту.

Візьміть гіпотетичний клієнт Python, який використовується urllib2для подання запитів. Напевно, у вас є якийсь метод у клієнта, назвемо його get(), який має в ньому виклик urllib2.Request(). Вам справді потрібно знущатися над дзвінком до власного класу get().

@patch('your.Client.get')
def test_with_mock(self, your_mock):
    your_mock.return_value({'some': 'json'})
    test_obj = your.Client.get_object(5)
    your_mock.assert_called_with('/the/correct/endpoint/5')

Цей дуже спрощений приклад використовує бібліотеку Mock Python's Mock для тестування гіпотетичного your.Clientкласу get_object()методом, який генерує правильний URL, щоб отримати щось із якогось API. Щоб зробити запит, клієнт викликає свій get()метод за допомогою цього URL-адреси. Тут цей метод знущається ( your.Client.get"латкується" так, щоб він your_mockзнаходився під контролем ), і тест перевіряє, чи потрібна потрібна кінцева точка.

Знущенний метод повертає налаштований JSON-відповідь ( your_mock.return_value), з якою повинен працювати клієнт, і ви зробите додаткові твердження, щоб перевірити, чи обробляє очікувані дані очікуваним способом.


Але як ви впевнені, що коли ви робите "правильний" запит, це фактичний правильний (у виробництві) запит? Тому що якщо я зрозумію вашу пропозицію, якщо API зміниться або порушиться, ваші тести працюватимуть. Хоча у виробництві це зовсім інша історія.
FrEaKmAn

1

Те, що ви описуєте, - це сценарій тестування інтеграції. Зазвичай вони трохи незручні для налаштування та зриву. Це робить їх повільними в ході і досить часто крихкими.

Підхід із світильниками настільки ж незручний і незграбний, але це стандартний спосіб, коли деякі рамки йдуть, наприклад, рейли, і він вже підтримується. Їм потрібен абстрактний тестовий випадок або щось подібне, щоб підготувати базу даних із світильниками. (Остерігайтеся незвичного іменування тестових категорій у Rails, одиничні тести з пристосуваннями DB строго говорять також про інтеграційні тести)

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

Якщо ви вважаєте, що це занадто багато (у сенсі надмірних) зусиль, то врахуйте, що підхід із кріпленнями для баз даних робить саме це: використання додаткових тестових засобів для маніпулювання базою даних або станом програми.

Я не думаю, що ця дискусія не має жодного стосунку до HTTP без громадянства. HTTP є без громадянства, але додаток, безумовно, ні, в більшості випадків. Це звучить трохи схоже на вас, де шукаєте строгості REST. Ви можете так само, щоб усі ресурси були повністю створеними, читабельними та видаленими. У такому випадку ви можете просто виконати всі налаштування та закрити за допомогою звичайних засобів API. Однак це часто не робиться на практиці, оскільки ви не хочете включати певні операції з ділового розуміння вашої заявки, принаймні не за межами тестового середовища.


1

Патч мавп

У моїй роботі ми робимо ATDD, використовуючи існуючий фреймворк xUnit та мережеві виклики мавпових виправлень між клієнтом та сервером. У цьому ж просторі процесу ми завантажуємо клієнта, мавпа виправляє мережевий виклик у верхню частину коду стека сервера REST. Після цього всі дзвінки надходять від клієнта так, як вони були, і серверний код отримує запити саме так, як вони зазвичай з'являються.

Переваги

  • немає необхідності синхронізуватись із запуском сервера (тому що немає сервера)
  • використовувати класичні налаштування блоку та метод схуднення для керування такими предметами, як світильники
  • можливість використання макетів / заглушок та інших мавпових пластирів для більш тонкого зернистого контролю тесту
  • можна записати за допомогою фреймворку xUnit

Компроміси

  • не виставляє багатопроцесових взаємодій / проблем (блокування, голодування ресурсів тощо)
  • не виставляє проблем із кількома серверами (серіалізація даних, стиль кластеризації)
  • не виставляє проблем з мережею, оскільки це моделюється (помилки доступу, таймаут та ін.)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.