Mocking WebService, используемый портом Biztalk Request-Response - PullRequest
9 голосов
/ 02 ноября 2008

Я использую BizUnit для модульного тестирования моих оркестровок Biztalk, но некоторые оркестровки используют WebService, и их тестирование больше похоже на интеграционное тестирование, чем модульное тестирование.

Я знаком с использованием фальшивой инфраструктуры для имитации сгенерированных прокси-объектов, чтобы протестировать веб-сервис из приложения Windows Forms, но я бы хотел сделать это более интегрированным способом в запросе. порт ответа?

Как бы вы подошли к этой проблеме?

Ответы [ 7 ]

7 голосов
/ 07 ноября 2008

Это относится к одному из моих главных раздражителей как разработчика BizTalk - BizTalk не подходит для модульного тестирования. Начиная с того факта, что 99% ваших интерфейсов в приложениях BizTalk основаны на сообщениях и имеют огромное количество возможных входных данных, вплоть до непрозрачного характера оркестровок, BizTalk не предлагает никакого реального способа тестирования функциональных блоков, а ... ну ... ед.

Для BizTalk интеграционные тесты, к сожалению, часто являются единственной игрой в городе.

Это приводит к тому, что из-за отсутствия ошибки со стороны Кевина Смита BizUnit является (IMO) неверным. Лучшее имя, возможно, будет BizIntegrationIt. BizUnit предлагает ряд инструментов, которые помогают в интеграционном тестировании, большинство тестов, таких как проверка того, был ли файл записан в заданный каталог или отправка HTTPRequest в местоположение BizTalk HTTPReceive, строго говоря, тестирование интеграции.

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

Я никогда не думал о каком-либо хорошем способе сделать это, но ниже приведено решение, которое должно работать, я сделал вариации каждой части этого в отдельности, но никогда не пытался объединить их все вместе в этой конкретной форме.

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

Макет веб-сервиса с использованием специального адаптера

Если вы создаете собственный адаптер запроса-ответа, вы можете подключить его к порту отправки вместо адаптера SOAP. Затем вы можете указать свойства адаптера, которые позволят ему вести себя как макет вашего веб-сервиса. Адаптер был бы похож по замыканию на адаптер с обратной связью, но допускал бы внутреннюю логику насмешек.

Вещи, которые вы можете включить в свойства адаптера:

  • Ожидаемый документ (возможно, место на диске, которое указывает пример того, что вы ожидаете, что ваше приложение BizTalk отправит на веб-сервис).
  • Ответный документ - документ, который адаптер отправит обратно в модуль обмена сообщениями.
  • Особые ожидания для теста, такие как значения поиска в элементах документа.

Вы также можете настроить собственный адаптер для записи на диск и настроить шаг BizUnit для проверки записанного файла.

Создание пользовательского адаптера нетривиально, но возможно, вы можете хорошо начать с BizTalk Adapter Wizard , а здесь есть статья о развертывании пользовательских адаптеров здесь .

В коде, сгенерированном мастером, есть ошибка, вам нужно изменить new Guid(""), на new Guid().

Есть также несколько примеров создания пользовательских адаптеров в BizTalk SDK.

Другой вариант - использовать простую http-страницу и ответ на запрос HTTP, как обсуждено здесь , вся ваша логика идет на http-странице. Это, вероятно, проще, если вы счастливы, имея http-вызов и настраивая порт IIS для прослушивания вашего теста.

Инициализация юнит-тестов

Вы можете импортировать файлы привязки в приложение BizTalk, используя файл .bat.

Если вы создаете новый файл привязки для каждого запускаемого теста, а также для настройки стандартного приложения, вы можете запустить соответствующий пакетный файл, чтобы применить правильную привязку.

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

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

Проверка содержимого сообщения

И последнее, что вы могли бы рассмотреть, чтобы действительно связать все это вместе, - это какой-то способ проверки содержимого сообщений. Вы можете сделать это в своем фиктивном адаптере, но это очень быстро утомительно для больших сообщений или для большого количества возможных входных сообщений.

Один из вариантов - создать собственный конвейер, который вызывает Schematron для проверки полученных файлов. Schematron - это язык схем, который обеспечивает гораздо более высокий уровень проверки файлов, чем xsd, поэтому вы можете проверить такие вещи, как «Если элемент x содержит это содержимое, я ожидаю, что элемент y будет присутствовать».

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

3 голосов
/ 09 ноября 2008

Как соавтор BizUnitExtensions (www.codeplex.com/bizunitextensions), я согласен, что название «unit» в BizUnit может сбивать с толку, но для Biztalk «интеграционный тест» - это модульный тест. Некоторые люди из Biztalk успешно использовали макеты для тестирования компонентов конвейера и другие тестовые наборы (+ BizUnit / Extensions) для тестирования схем и карт.

К сожалению, оркестровки непрозрачны. Но есть веские причины для этого.

(a) Из-за огромной системы подписки в окне сообщений - которую оркестрации используют при активации и т. Д., Невозможно запустить какой-либо «виртуальный» процесс для размещения оркестровки (что можно сделать для конвейеров. Томас Рестрепо сделал что-то в этом направлении).

(b) Кроме того, как этот виртуальный процесс будет обрабатывать постоянство и обезвоживание ?. Держу пари, что у людей, использующих WF, возникнет та же проблема при попытке полностью протестировать рабочий процесс.

(c) мы не работаем с C # напрямую, так что нет способа, которым мы можем «внедрить» макет интерфейс в код оркестрации.

(d) Оркестровка на самом деле не является «единицей». это составной элемент. Единицами измерения являются сообщения, поступающие в окно сообщения и из него, а также внешние компоненты, вызываемые через формы выражений. Поэтому даже если вы можете внедрить ложный интерфейс веб-сервиса, вы не сможете внедрить ложные окна сообщений, наборы корреляций и другие вещи.

Одна вещь, которую можно сделать для оркестровок (и я рассматривал добавление в библиотеку BizUnitExtensions, чтобы сделать это), это связать с инструментом OrchestrationProfiler, так как этот инструмент дает довольно подробный отчет обо всех формах и так или иначе проверьте, что отдельные шаги были выполнены (и, возможно, время, которое потребовалось для выполнения). Это может зайти довольно далеко, сделав оркестровку более похожей на белый ящик. Также учитывая, что отладчик оркестровки показывает много значений переменных, безусловно, должна быть возможность получить эту информацию через API, чтобы показать, какие значения переменных были в данной точке для данного экземпляра.

Вернемся к вопросу Ричарда, но у моей предыдущей команды разработчиков было решение. По сути, мы создали общий настраиваемый HttpHandler, который анализировал входящие запросы на обслуживание и возвращал предварительно заданные ответы. Отправленный ответ был настраиваемым на основе таких условий, как XPath. В файлах привязки BUILD и DEV конечной точкой веб-службы была фиктивная. Это прекрасно сработало, изолировав среды BUILD и DEV от сторонних веб-сервисов. Это также помогло в подходе «сначала контракт», где мы создали макет, и разработчик Orch использовал его, в то время как автор веб-сервиса продолжил работу и создал реальный сервис.

[Обновление: 17-FEB-09: этот инструмент теперь в кодплексе: http://www.codeplex.com/mockingbird. Если этот подход звучит интересно, проверьте его и дайте мне знать, что вы думаете об инструменте]

Теперь, прежде чем кто-то добавит старый каштан «ЧТО О MOCK OBJECT FRAMEWORKS», позвольте мне сказать, что приведенная выше утилита использовалась как для «потребителей» Biztalk, так и для пользователей, не являющихся Biztalk, НО я также работал с NMock2 и обнаружил, что это отличный способ макетировать интерфейсы и устанавливать ожидания при написании CLR-потребителей. (Я собираюсь изучить MoQ, TypeMock и т. Д. В ближайшее время). Однако он не будет работать с оркестровками по причинам, описанным выше.

Надеюсь, это поможет.

С уважением,

Бенджи

1 голос
/ 07 ноября 2008

Не.

Не проверяйте произвольные интерфейсы и не создавайте для них макеты.

Большинство людей, похоже, считают, что тестирование разработчиком (модулем) предназначено для тестирования нетривиальных, отдельных модулей функциональности, таких как отдельный класс. С другой стороны, также важно выполнить потребительское (приемочное / интеграционное) тестирование основных подсистем или всей системы.

Для веб-службы нетривиальная единица функциональности скрыта в классах, которые фактически выполняют значимое обслуживание, за коммуникационной проводкой. Эти классы должны иметь отдельные тестовые классы разработчика, которые проверяют их функциональность, но полностью без какой-либо проводки, ориентированной на веб-сервисы. Естественно, но, возможно, не очевидно, это означает, что ваша реализация функциональности должна быть отделена от вашей реализации проводки. Таким образом, ваши разработчики (юнит-тесты) никогда не должны видеть никакой специальной коммуникационной проводки; это является частью интеграции, и ее можно рассматривать (соответственно) как проблему «представления», а не как «бизнес-логику».

Клиентские (приемочные / интеграционные) тесты должны охватывать гораздо больший масштаб функциональности, но при этом не фокусироваться на вопросах «презентации». Именно здесь широко распространено использование шаблона Facade - предоставление подсистемы с унифицированным грубым тестируемым интерфейсом. Опять же, интеграция взаимодействия с веб-сервисом не имеет значения и реализуется отдельно.

Однако очень полезно реализовать отдельный набор тестов, который фактически включает интеграцию с веб-сервисом. Но я настоятельно рекомендую не тестировать только одну сторону этой интеграции: тестировать ее из конца в конец. Это означает создание тестов, которые являются клиентами веб-сервисов, как настоящий производственный код; они должны использовать веб-сервисы в точности так, как это делают реальные приложения, а это значит, что эти тесты служат примерами для тех, кто должен внедрять такие приложения (например, для ваших клиентов, если вы продаете библиотеку).

Итак, зачем идти ко всем этим неприятностям?

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

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

  3. Ваши интеграционные тесты подтверждают, что ваш уровень представления работает с вашим уровнем бизнес-логики, который теперь управляем, поскольку теперь вы можете игнорировать базовую функциональность (потому что вы отдельно протестировали ее выше). Другими словами, эти тесты ориентированы на тонкий слой симпатичного лица (GUI?) И коммуникационный интерфейс (веб-сервисы?).

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

  5. Вам не нужны никакие специальные инструменты, такие как тестовый инструмент специально для веб-сервисов. Вы используете инструменты / компоненты / библиотеки / методы, которые вы использовали бы в рабочем коде, точно так же, как вы использовали бы их в таком рабочем коде. Это делает ваши тесты более значимыми, поскольку вы не тестируете чужие инструменты. Это экономит ваше время и деньги, поскольку вы не покупаете, не развертываете, не разрабатываете и не поддерживаете специальный инструмент. Однако, если вы тестируете через графический интерфейс (не делайте этого!), Вам может понадобиться один специальный инструмент для этой части (например, HttpUnit?).

Итак, давайте разберемся. Предположим, что мы хотим обеспечить некоторую функциональность для отслеживания ежедневного меню кафетерия (потому что мы работаем в мегакорпорации с собственным кафе в здании, как у меня). Допустим, мы нацелены на C #.

Мы создаем некоторые классы C # для меню, пунктов меню и других детальных функциональных возможностей и связанных с ними данных. Мы устанавливаем автоматическую сборку (вы делаете это, верно?), Используя nAnt, который выполняет тесты разработчика, используя nUnit, и мы подтверждаем, что мы можем создать ежедневное меню и просматривать его с помощью всех этих маленьких кусочков.

У нас есть некоторое представление о том, куда мы идем, поэтому мы применяем шаблон Facade, создавая один класс, который предоставляет несколько методов, скрывая большинство мелкозернистых фрагментов. Мы добавили отдельный набор клиентских тестов, которые работают только через этот новый фасад, как и клиент.

Теперь мы решили, что мы хотим предоставить веб-страницу нашим работникам, занятым в мегакорпоративном обучении, чтобы проверить меню современной столовой. Мы пишем страницу ASP.NET, заставляем ее вызывать наш фасадный класс (который становится нашей моделью, если мы делаем MVC) и разворачиваем ее. Поскольку мы уже тщательно протестировали класс фасадов с помощью наших пользовательских тестов, и поскольку наша отдельная веб-страница настолько проста, мы отказываемся от написания автоматических тестов для веб-страницы - ручной тест с использованием нескольких коллег по знаниям поможет.

Позже мы начинаем добавлять некоторые новые важные функции, например, возможность предварительно заказать обед на день. Мы расширяем наши детальные классы и соответствующие тесты разработчика, зная, что наши уже существующие тесты защищают нас от взлома существующей функциональности. Аналогично, мы расширяем наш класс фасадов, возможно, даже отделяя новый класс (например, MenuFacade и OrderFacade) по мере расширения интерфейса, с аналогичными дополнениями к нашим тестам для клиентов.

Теперь, возможно, изменения на веб-сайте (две страницы - это веб-сайт, верно?) Делают ручное тестирование неудовлетворительным. Итак, мы предлагаем простой инструмент, сравнимый с HttpUnit, который позволяет nUnit тестировать веб-страницы. Мы реализуем ряд интеграционных / презентационных тестов, но на основе фиктивной версии наших фасадных классов, потому что дело здесь просто в том, что веб-страницы работают - мы уже знаем, что работают фасадные классы. Тесты проталкивают данные через фиктивные фасады только для того, чтобы проверить, что данные успешно перешли на другую сторону. Ничего больше.

Конечно, наш грандиозный успех побуждает генерального директора потребовать (потребовать), чтобы мы представили веб-приложение для BlackBerrys мегакорпорации. Итак, мы внедрили несколько новых страниц и новую батарею интеграционных тестов. Нам не нужно прикасаться к тестам разработчика или заказчика, потому что мы не добавили новых основных функций.

Наконец, технический директор просит (требует), чтобы мы распространили наше приложение для кафетерия на всех работников роботов мегакорпорации - вы заметили их в последние несколько дней? Итак, теперь мы добавляем слой веб-сервисов, который взаимодействует через наш фасад. Опять же, никаких изменений в нашей основной функциональности, наших тестах для разработчиков или наших клиентских тестах. Мы применяем шаблон Adapter / Wrapper, создавая классы, которые предоставляют фасад с эквивалентным API веб-службы, и мы создаем клиентские классы для использования этого API. Мы добавили новую батарею интеграционных тестов, но они используют простой nUnit для создания клиентских API-классов, которые связываются через проводку веб-службы с API-классами сервисной стороны, которые вызывают фиктивные классы фасадов, которые подтверждают, что наша проводка работает.

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

В результате мы получили прочное ядро ​​функциональности (уровень бизнес-логики), которое оказалось зрелым (гипотетически). У нас есть три реализации уровня представления: веб-сайт, предназначенный для настольных компьютеров, веб-сайт, предназначенный для BlackBerrys, и API веб-службы.

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

0 голосов
/ 26 ноября 2008

Это способ сделать это:

Вернемся к вопросу Ричарда, мой предыдущая команда разработчиков имела решение. По сути, мы написали универсальный настраиваемый HttpHandler, который проанализировал входящие запросы на обслуживание и возвратил заранее заданные ответы. ответ отослан был настраиваемым на основе таких условий, как XPath

0 голосов
/ 04 ноября 2008

Мне не приходилось делать это некоторое время, но когда я тестировал свои приложения Biztalk, я всегда использовал либо мыло, либо студию веб-сервисов. Я был в состоянии проверить различные входные значения без усилий.

0 голосов
/ 04 ноября 2008

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

Другой способ может заключаться в том, чтобы как-то обернуть WebDev.WebHost.dll и использовать его ... Фил Хаккк обсуждает это в этом посте .

Это также обсуждалось ранее на SO здесь .

Пожалуйста, дайте нам знать, если вы найдете другое решение для этого!

0 голосов
/ 03 ноября 2008

Отказ от ответственности: я работаю в Typemock.

Я не совсем уверен, что вам нужно делать, но я думаю, что следующая ссылка - хорошее начало:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...