Как сделать интеграционное тестирование для (Angularjs) веб-приложений

Я занимаюсь разработкой веб-приложения. Он состоит из 2 частей. Сервер остальных узлов и клиент angularjs.

Приложение структурировано следующим образом: Rest Server < -> Api Module < -> Angular App

Сервер в настоящее время хорошо протестирован. У меня есть модульные тесты и интеграционные тесты. Интеграционные тесты получают доступ к реальной базе данных и вызывают остальные API через http. Я думаю, что это настолько высокий уровень, насколько это возможно для тестирования сервера. Интеграционные тесты тоже работают быстро. Я вполне уверен, что способ тестирования сервера достаточен для моего варианта использования, и я доволен результатами.

Однако я изо всех сил пытаюсь протестировать приложение angularjs. У меня есть модульные тесты для соответствующих директив и модулей. Написание этих не было проблемой.

Я хотел бы написать интеграционные тесты, которые охватывают пользовательские сценарии. Что-то вроде сценария регистрации: пользователь посещает веб-сайт, переходит к форме регистрации и отправляет форму с данными.

Команда angularjs переходит от нг-сценариев к транспортиру . Транспортир использует Selenium для запуска тестов. Поэтому существует две области: область приложения и область тестирования.

Теперь я могу думать о трех разных абстракциях, которые я мог бы использовать. И я не уверен, какой из них подходит мне лучше всего.

  • Макет модуля Api
  • Макет сервера отдыха
  • Использование полного сервера

Макет модуля Api

В В этом случае мне не нужно настраивать сервер. Все взаимодействия выполняются в браузере

Преимущество:

  • Сервер не требуется

Недостаток:

  • API находится в области видимости браузера, и я должен вмешаться в это.

Мне действительно нравится это решение, но мне трудно издеваться над API. Api необходимо изменить в области видимости браузера. Поэтому мне нужно отправить модификацию из теста в браузер. Это можно сделать , однако я не вижу, как я мог запустить утверждения типа mockedApi.method.wasCalledOnce() в области тестирования

Mock the Rest Server

Преимущество:

  • Клиент будет неизменен
  • Только одна область действия для решения

Недостаток:

  • Необходимо настроить остальные маршруты

Я мог бы создать полный Mock Rest Server в nodejs. Тесты транспортира пишутся в nodejs, таким образом контроль сервера может быть сделан в тесте. Перед запуском теста я могу сказать серверу, как реагировать. Примерно так: server.onRequest({method: 'GET', url: '/'}).respondWith('hello world')

Тогда я могу сделать такие утверждения, как wasCalledOnce

Использовать полный сервер с базой данных

Каждый тест выполняется с полным сервером и может добавить элементы в базу данных. После каждого теста можно посмотреть ожидаемые элементы в базе данных

Преимущество:

  • Можно быть уверенным, что если эти тесты запущены, приложение работает в тестируемом сценарии использования.

Недостаток:

  • Я уже провел довольно интенсивный тест интеграции с остальным сервером. Это похоже на то же самое снова.
  • Настройка зависит от полного сервера.

Текущее заключение

  • Насмешка над Api полностью отделит сервер и клиента.
  • Использование Mock Api было бы тестом более высокого уровня, но потребовало бы поддельного сервера
  • Выполнение полного интеграционного теста дало бы наилучшую надежность, но это также сильно зависит от кода сервера

Что мне выбрать? Что бы вы сделали?

30
задан 18.05.2020, 01:40

5 ответов

Это отличный вопрос, который не имеет ничего общего с конкретным инструментом. Мне пришлось столкнуться с той же проблемой в большом проекте «с нуля» (то есть с нуля).

Здесь существует проблема со словарем: слово «макет» используется повсеместно, а то, что вы называете «интеграционным тестом», больше означает «полное сквозное автоматизированное функциональное тестирование». Не обижайтесь, просто четкая формулировка поможет решить проблему.

Вы на самом деле предложили правильный ответ: # 2 заглушите остальной сервер. # 1 выполнимо, но скоро его будет слишком сложно разрабатывать и поддерживать, # 3 - отличная идея, но не имеет ничего общего с тестированием пользовательского интерфейса и его проверкой.

Чтобы добиться высокой надежности вашего внешнего интерфейса, независимо от вашего внутреннего, просто заглушите остальной сервер, то есть разработайте глупый простой REST-сервер, который будет идемпотентным, т.е. е. ВСЕГДА ответит на одно и то же HTTP-запрос. Соблюдение принципа идемпотентности сделает разработку и тестирование очень и очень простым, чем любой другой вариант.

Затем для одного теста вы проверяете только то, что отображается на экране (тестирование сверху) и что отправляется на сервер (тестирование снизу), так что полный стек пользовательского интерфейса тестируется только один раз.

Полный ответ на этот вопрос заслуживает целой статьи в блоге, но я надеюсь, что вы можете почувствовать, что делать из того, что я предлагаю.

С наилучшими пожеланиями

3
ответ дан 18.05.2020, 01:40
  • 1
    Мой фаворит, поскольку это решает проблему цели. Это инициировало средства блокировки всплывающих окон хотя? – Jon P 07.01.2020, 20:15

По моему мнению, надругаться над сервером REST - лучший, более чистый вариант. Попробуйте Mountebank ( http://www.mbtest.org ). Удивительный инструмент службы виртуализации.

0
ответ дан 18.05.2020, 01:41
  • 1
    @Ness, Спасибо! Довольный, это помогло.. – Saumil 07.01.2020, 20:16

Я думаю, что ответил на тот же вопрос в группе Google Protractor. Я во многом согласен с тем, что вам не нужен сервер, а нужно, чтобы весь мой тестовый код находился в одном месте (в Protractor) и не делился между Protractor и браузером. Чтобы сделать это, я взял дело в свои руки и разработал прокси для службы $ httpBackend, которая работает в Protractor. Это позволяет настроить службу $ httpBackend так, как если бы она работала в Protractor. Я работал над этим уже некоторое время, и на данный момент он достаточно полнофункциональный. Было бы здорово, если бы вы посмотрели и дали мне знать, если я что-то упустил.

https://github.com/kbaltrinic/http-backend-proxy

4
ответ дан 18.05.2020, 01:42
  • 1
    В тех случаях тогда необходимо просто вызвать функцию, которая выполняет те действия непосредственно, вместо того, чтобы фальсифицировать событие щелчка на кнопке. – Rory McCrossan 07.01.2020, 20:15
  • 2
    Это выглядит мило. Я взгляну! –  18.05.2020, 01:42

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

Подробнее здесь: http://www.syntaxsuccess.com/viewarticle/angular-integration-tests

3
ответ дан 18.05.2020, 01:42

Это отличный вопрос. Вот как я бы это сделал:

Поскольку у вас уже есть угловые модульные тесты для соответствующих директив и модулей, это прекрасно.

Еще одна отличная вещь - это то, что тесты интеграции вашего сервера обращаются к реальной базе данных, а также проверяют работу остальных API через http.

Так почему бы просто не добавить несколько высокоуровневых интеграционных тестов, которые одновременно включают в себя angular и ваш сервер.

Если вы можете избежать насмешек, почему бы не сохранить работу, чтобы сохранить дополнительный код, если это возможно.

Также хорошее чтение: http://blog.ericbmerritt.com/2014/03/25/mocking-is-evil.html

0
ответ дан 18.05.2020, 01:43
  • 1
    Это - единственная вещь, которая работала на мою ситуацию! Некоторые люди даже говорят, что щелчок jQuery просто работает - нисколько на меня. Это решение является потрясающим. – Ness 07.01.2020, 20:16

Теги

Похожие вопросы