 | Уровень сложности: средний Дональд Вайнз, ведущий ИТ-архитектор, IBM
26.08.2009
Эта статья познакомит вас с основами разработки приложений для среды SOA через тестирование. В ней показано, как разрабатывать тестовые примеры для схем преобразования данных SDO еще до предоставления их для использования другими SCA-модулями, и приведены пошаговые инструкции по написанию таких тестовых примеров и их выполнению с использованием JUnit, Cactus и IBM ® WebSphere® Integration Developer.
Из журнала IBM WebSphere Developer Technical Journal.
Вступление
В последнее время в программировании произошли две существенные перемены - все более широкое применение разработки ПО через тестирование и непрерывной интеграции. В рамках перехода к гибким (agile) методологиям разработки программного обеспечения в течение нескольких лет эти технологии применялись в создании обычных Java™-приложений, а в последнее время стали использоваться и для построения SOA-решений.
В связи с этим на сайте developerWorks была опубликована статья, в которой описаны все новые функции IBM WebSphere Integration Developer V6.1, позволяющие создавать контрольные примеры и запускать их автоматически, нажатием одной кнопки.
Еще одна серия статей посвящена использованию JUnit и Cactus для тестирования компонентов Service Component Architecture (SCA), компонентов BPEL и задач ручной обработки. Эти статьи будут полезны всем Java-разработчикам, работающим в среде SOA. В дополнение к этим источникам данная статья, состоящая из двух частей, освещает еще две не менее важные темы:
-
Модульное тестирование преобразования данных весьма важно на ранних стадиях разработки SOA-проекта. Тестирование преобразования данных особенно необходимо для интерфейсов неотлаженных служб, когда данные либо еще ненадежны, либо непостоянны, но также полезно и для интерфейсов тщательно разработанных служб. Благодаря таким тестам вам меньше придется думать о рефакторинге типов данных. Можно внести нужные изменения, заново протестировать преобразование, а затем те модули, которые его используют.
-
Непрерывная интеграция -- полностью автоматизированная и воспроизводимая сборка программы (включая тестирование), которая запускается по несколько раз в день, -- широко распространенная технология для работы с обычными приложениями. Для применения этой технологии гибкой разработки в SOA-средах необходимо обеспечить возможность выполнения модульного тестирования как части регулярной плановой интеграционной сборки. Это делается за пределами интегрированной среды разработки (IDE), например, WebSphere Integration Developer, поэтому обычно требуется запускать модульное тестирование с помощью Ant.
В данной статье показано, как протестировать преобразование данных, не затрагивая использующих его SCA-модулей. Тестирование преобразования данных сочетается со стандартной практике определения типов общих данных и преобразования данных в совместно используемой библиотеке, позволяя выполнить проверку библиотеки до того, как открыть модулям доступ к ней. Библиотеку можно протестировать даже до создания модулей. Разработка ПО через тестирование не запрещает такого подхода.
Во второй части рассматривается применение непрерывной интеграции в SOA-среде, с применением инструментального средства автоматизированной сборки, подобного Ant, не только для запуска тестирования элементов программы, но и для создания тестовых отчетов и оповещения разработчиков по электронной почте об ошибках во время тестирования.
Модульное тестирование преобразования данных
Чтобы понять, как тестировать преобразование данных, давайте рассмотрим следующий сценарий:
-
У вас есть служба очистки адресов, которая проводит верификацию адреса, но необходимо, чтобы адреса поступали к ней в виде значений, разделенных запятыми – т.е. в библиотеке есть тип данных AddressCSV.
-
Все остальные блоки SOA-решения понимают адреса тогда, когда все части адреса занесены в отдельные поля, например, company, addressLine1, и т.д. – для чего в библиотеке есть тип данных Address.
-
В библиотеке хранится две схемы преобразования данных: одна преобразует адрес из Address в AddressCSV (рисунок 1), а вторая – из AddressCSV в Address (рисунок 2).
Рисунок 1. Преобразование данных Address_To_AddressCSV
Рисунок 2. Преобразование данных AddressCSV_To_Address
Как видно из рисунков, схемы довольно просты и пошаговое преобразование (от поля к полю) достаточно прямолинейно. Однако при работе с большими бизнес-объектами схемы преобразования данных могут быть весьма сложными, и зачастую трудно определить, какие атрибуты отображаются друг в друга. Разработка схемы преобразования данных может оказаться довольно трудоемкой задачей, подверженной ошибкам, что, в свою очередь, подчеркивает важность многократного тестирования.
Чтобы протестировать показанные схемы преобразования данных, необходимо написать несколько тестовых примеров JUnit. Для нашего примера подготовлены образцы кода, которые можно загрузить. Пример кода сохранен в файле которые можно загрузить. Примеры кода сохранены в файлах переноса проекта, поэтому их можно импортировать в рабочую область WebSphere Integration Developer V6.1. После импорта откройте перспективу Business Integration, чтобы увидеть три указанных примера:
-
L_AddressCleansingService: В этой библиотеке находятся типы данных и схемы преобразования данных для композитного приложения, которые будут многократно использоваться модулями нашего SOA-решения.
-
T_AddressCleansingService: Этот модуль используется для тестирования схем преобразования данных и будет развертываться на IBM WebSphere Process Server только в средах тестирования. Он не является частью SOA-решения.
-
T_AddressCleansingServiceJUnitWeb: Этот динамический Web-проект содержит тестовые примеры JUnit, которые будут выполняться в контейнере WebSphere Process Server. Это часть тестового модуля T_AddressCleansingService.
В нашем сценарии предполагается, что схемы преобразования и типы данных библиотеки уже существуют, поэтому в рамках данной статьи мы не будем рассматривать, как их создавать. Их описание можно посмотреть в библиотеке. Информацию о том, как создавать схемы преобразования данных, можно почерпнуть из обзора WebSphere Integration Developer.
Далее в статье мы опишем три этапа тестирования преобразования данных:
-
Создание тестового модуля и Web-проекта
-
Разработка тестовых примеров и схем преобразования данных
-
Выполнение тестовых примеров
В последующих разделах приведено подробное описание этих шагов.
1. Создание тестового модуля и Web-проекта
Для реализации этого шага вы можете выполнить описанные ниже действия или просто скачать и импортировать файл переноса проекта, чтобы воспользоваться предоставленным тестовым модулем и Web-проектом. Если вы выберете второй вариант, сразу переходите к шагу 2.
Чтобы создать тестовый модуль:
-
В перспективе Business Integration WebSphere Integration Developer откройте вид Business Integration. Щелкните правой кнопкой мыши и выберите New
=> Module. В диалоговом окне New Module введите имя T_AddressCleansingService и нажмите Finish.
-
Чтобы создать динамический Web-проект, переключитесь в перспективу J2EE.
Нажмите правой кнопкой мыши на T_AddressCleansingServiceApp и выберите New =>
Dynamic Web Project. В диалоговом окне New Dynamic Web Project введите T_AddressCleansingServiceJUnitWeb и нажмите Finish.
-
Затем для тестирования создайте связь между тестовым модулем и библиотекой, в которой хранятся типы данных и схемы преобразования данных. Для этого переключитесь в перспективу Business Integration. Выберите T_AddressCleansingService и дважды щелкните левой кнопкой мыши, чтобы открыть редактор Dependency. Разверните Librariesи используйте функцию Add для добавления L_AddresCleansingService.
-
Далее в тестовую модель необходимо добавить Log4J, JUnit и инфраструктуру Cactus. Для этого поместите эти библиотеки в папку Web-inf\lib проекта T_AddressCleansingServiceJUnitWeb:
-
Наконец, необходимо добавить описание сервлета в файл web.xml Web-приложения. Для этого вырежьте код из листинга 1 и вставьте его в дескриптор развертывания динамического Web-приложения между уже существующим описанием и файлом приветствия:
Листинг 1
<display-name>T_AddressCleansingServiceJUnitWeb</display-name>
<servlet>
<servlet-name>ServletRedirector</servlet-name>
<servlet-class>
org.apache.cactus.server.ServletTestRedirector
</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1 used for testing</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>ServletTestRunner</servlet-name>
<servlet-class>
org.apache.cactus.server.runner.ServletTestRunner
</servlet-class>
</servlet>
<servlet-maping>
<servlet-name>ServletRedirector</servlet-name>
<url-pattern>/ServletRedirector</url-pattern>
</servlet-maping>
<servlet-maping>
<servlet-name>ServletTestRunner</servlet-name>
<url-pattern>/ServletTestRunner</url-pattern>
</servlet-maping>
<welcome file list> |
2. Создание тестовых примеров и схем преобразования данных
Теперь создадим тестовый пример для преобразования данных Address_To_AddressCSV. Этот тестовый пример наполняет входной объект Address содержимым, инициирует преобразование для создания выходного объекта и затем сравнивает полученный объект AddressCSV с ожидаемыми результатами. Если они идентичны, то тест считается успешным, в противном случае - неудачным. (В прилагаемом файле переноса проекта также содержится тестовый пример для преобразования данных AddressCSV_To_Address.)
Создание модульного теста предполагает следующие шаги:
-
Создание тестового класса
Типичная модель программирования JUnit предусматривает создание тестового класса с помощью TestCase, находящегося в JUnit. Фреймворк Cactus представляет собой расширение JUnit, которое позволяет запускать модульные тесты внутри контейнера. Так как мы работаем с инфраструктурой Cactus, то будем расширять тестовый класс Cactus - class org.apache.cactus.ServletTestCase. Для этого:
- Перейдите в перспективу Web, в отображение Project Explorer и разверните Dynamic Web
Projects => T_AddressCleansingServiceJUnitWeb => Java Resources => JavaSource.
- Для того, чтобы создать подходящий пакет, щелкните правой кнопкой мыши на Java Source и выберите New => Package. Щелкните правой кнопкой мыши на пакете и выберите New => Class, чтобы создать класс, и введите код, например:
Листинг 2
package com.ibm.issw.service.addresscleansing.test;
import org.apache.cactus.ServletTestCase;
public class AddressCleansingServiceTest extends ServletTestCase { |
-
Разработка методов setup() и teardown()
Фреймворк JUnit предоставляет методы для настройки среды для тестового примера и для удаления среды после прогона тестового примера. Последовательность действий такова: вызывается setUp(), вызывается метод testxxx(), вызывается tearDown(). Такая последовательность выполняется для каждого метода testXXX() тестового примера. В листинге 3 показаны примеры методов setUp() и tearDown().
Листинг 3
private DataObject expectedAddress;
private String expectedWholeAddress;
private DataObject expectedAddressCSV;
private MapService mService;
private static Logger logger = Logger.getLogger(
AddressCleansingServiceTest.class );
protected void setUp() throws Exception {
expectedAddress = createAddress(
"IBM Corporation","1133 Westchester Avenue",
"","White Plains","NY","10604");
expectedWholeAddress = createWholeAddress(
"IBM Corporation","1133 Westchester Avenue",
"","White Plains","NY","10604");
expectedAddressCSV = createAddressCSV(expectedWholeAddress);
// Get the map service so we can invoke the mapping operation.
mService = (MapService) ServiceManager.INSTANCE.locateService(
"com/ibm/wbiserver/map/MapService");
}
protected void tearDown() throws Exception {
expectedAddress = null;
expectedAddressCSV = null;
expectedWholeAddress = null;
mService = null;
} |
В листинге 3 показано:
- Описание частных элементов данных, общих для всех методов тестирования. Эти элементы данных инициализируются в setUp(), используются в testXX() и уничтожаются в tearDown.
- Создание службы журналирования для записи информации внутри методов тестирования.
- Создание и инициализация "фактических" входных данных SDO для последующей передачи на преобразование с помощью метода createAddress(). В результате данного шага просто создается Address SDO и ему присваиваются заданные значения. (Реализация приведена в файле переноса проекта.)
- Создание и инициализация "предполагаемых" выходных данных SDO для того, чтобы можно было сравнить их с фактическими выходными данными SDO, которые были возвращены после преобразования. Данные действия реализуются с помощью методов createWholeAddress() и createAddressCSV(). (Реализация данного шага показана в файле переноса проекта .)
-
Создание методов тестирования
Соглашение о присвоении имен JUnit гласит, что названия всех методов должны начинаться со слова "test." Методы не имеют параметров и возвращают void. Неудачное завершение тестирования сигнализируется появлением непроверяемых ошибок, обычно на основе assertion- и failure-методов, предоставляемых JUnit. Завершение работы метода тестирования означает удачное завершение тестирования. Для нашего примера метод тестирования выглядит так, как показано в листинге 4.
Листинг 4
public void testAddress_To_AddressCSVMap()
throws WBIMapNotFoundException, WBIMapFailureException, WBIMapServiceException {
try {
logger.debug("Invoking Address_To_AddressCSV map.");
BOFactory bof = (BOFactory)ServiceManager.INSTANCE.locateService(
"com/ibm/websphere/bo/BOFactory");
DataObject actualAddressCSV = bof.create(
"http://L_AddressCleansingService", "AddressCSV");
HashMap inputMap = new HashMap();
HashMap outputMap = new HashMap();
inputMap.put("Address", expectedAddress);
outputMap.put("AddressCSV", actualAddressCSV);
mService.transform("http://L_AddressCleansingService",
"Address_To_AddressCSV", inputMap, outputMap, (ExecutionContext)null);
assertEquals(actualAddressCSV.getString("wholeAddress"),
expectedAddressCSV.getString("wholeAddress"));
} catch (WBIMapNotFoundException e) {
logger.debug("WBIMapNotFoundException: " + e.getMessage());
throw e;
} catch (WBIMapFailureException e) {
logger.debug("WBIMapFailureException: " + e.getMessage());
throw e;
} catch (WBIMapServiceException e) {
logger.debug("WBIMapServiceException: " + e.getMessage());
throw e;
}
} |
В листинге 4 показано:
- Использование Log4J для распечатки отдельных сообщений во время тестирования. Обратите внимание, что файл атрибутов Log4J необходимо указать в classpath, чтобы его могли использовать каналы (appenders). Для этого добавьте папку в classpath сервера приложений. А именно:
- Откройте консоль администратора.
- Перейдите в Application servers => server1 => Process Definition =>
Java Virtual Machine.
- Как показано в листинге 5, добавьте название той папки, в которую был помещен файл log4j.properties в classpath.
Листинг 5
log4j.rootLogger=WARN, RootAppender, ConsoleAppender
log4j.appender.ConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleAppender.layout.ConversionPattern=[%d] %-5p %c{2} - %m%n
log4j.logger.com.ibm.issw=DEBUG |
- Запуск процесса преобразования данных с помощью метода transform(). В нашем примере используется общий метод transform(), который инициирует преобразование одного или нескольких SDO в другой SDO, однако можно использовать и метод simpleTransform(). Фрагмент программы с использованием метода simpleTransform() показан в листинге 6.
Листинг 6
mService.simpleTransform(
" http://L_AddressCleansingService”,
"Address_To_AddressCSV"
input,
output); |
- Ряд assertion-операторов над данными, которые возвращает команда, в частности, вы проверяете определение преобразования и добавляете операторы контроля для каждого преобразования. Для этого необходимо применить get-методы к входному и выходному объектам данных и использовать JUnit-метод assertEquals().
Теперь, имея этот код, можно запустить тестирование.
3. Запуск тестовых примеров
Чтобы запустить тест:
-
Во-первых, добавьте модуль тестирования на сервер и убедитесь, что сервер запущен.
-
В перспективе Business Integration перейдите к виду Servers. Щелкните правой кнопкой мыши на сервере, выберите Add Remove Projects, и добавьте на сервер T_AddressCleansingServiceApp. Теперь у вас есть тестовый класс, который можно запустить.
-
Чтобы запустить тестовый класс, перейдите в перспективу J2EE, вид Project Explorer. В меню Run сначала выберите класс AddressCleansingServiceTest, а затем Run... .
-
В диалоговом окне Run из списка возможных конфигураций (Configurations) выберите JUnit и нажмите кнопку New.
-
Перейдите в область Arguments. В поле аргументов VM введите аргумент -D (см. листинг 7). (Данный аргумент указывает localhost и порт 9083. Если для HTTP-запросов необходим другой сервер или порт, то внесите в строку все необходимые изменения.)
-Dcactus.contextURL=http://localhost:9083/T_AddressCleansingServiceJUnitWeb
|
-
Для запуска теста выберите Run. Теперь в виде JUnit можно посмотреть результаты работы теста (Рисунок 3).
Рисунок 3. Результаты работы теста
Теперь, когда стартовая компоновка создана, этот класс можно запускать повторно, просто выбирая его из списка и нажимая Run => JUnit Test.
Заключение
В этой статье рассказывается о том, как написать тестовые примеры для преобразования данных в контейнере WebSphere Process Server с помощью JUnit и Cactus. Данный подход позволяет создавать тестовые примеры для SDO типов данных и преобразования данных еще до реализации бизнес-процессов (SCA-модули), которые будут их использовать. Наличие таких тестов позволяет быстро проверить преобразование данных и поддерживает последующий рефакторинг типов данных, который может быть нужен в SOA-решении. Во второй части статьи будет показано, как запустить эти модульные тестовые примеры на сервере непрерывной интеграции.
Загрузка | Описание | Имя | Размер | Метод загрузки |
|---|
| Пример кода | TestingExample.zip | 972 КБ | HTTP |
|---|
Ресурсы - Примите участие в обсуждении материала на форуме.
- Оригинал статьи: Test-driven development in an SOA environment: Part 1: Testing data maps (EN)
-
Перевод тестирования компонентов в WebSphere Integration Developer на более высокий уровень, Ричард Грегори и Хун Тран, developerWorks, июнь 2008 г. (EN)
-
Надежное и систематическое функциональное тестирование для модулей Service Component Architecture, часть 1, Дэвид Артус, developerWorks, август 2006 г. (EN)
-
Надежное и систематическое модульное тестирование для модулей Service Component Architecture, часть 2, Дэвид Артус, developerWorks, сентябрь 2006 г. (EN)
-
Надежное и систематическое функциональное тестирование для модулей Service Component Architecture, часть 3, Дэвид Артус, developerWorks, январь 2007 г. (EN)
-
Путешествие по WebSphere Integration Developer, часть 7, Ричард Грегори, Рэнди Гиффен, Джейн Юнг и Грег Адамс, developerWorks, октябрь 2006 г. (EN)
Об авторе  | |  | Дональд Вайнз (Donald Vines) работает в IBM ведущим ИТ-архитектором и отвечает за подразделение миграции на WebSphere в Северной Америке. В настоящее время он работает над разработкой архитектурных решений для крупнейших клиентов IBM и является наставником для проектировщиков и разработчиков ПО в SOA и в проектах по модернизации предприятий. В прошлом он был техническим представителем группы OMG, самого крупного в мире комитета по стандартам, и занимался разработкой протокола взаимодействия ORB в сетях TCP/IP (IIOP), который теперь используется в Интернете. Дон имеет сертификаты сертифицированного бизнес-архитектора компании Sun, сертифицированного Java-программиста компании Sun и сертифицированного специалиста по UML2 от OMG. |
Выскажите мнение об этой странице
|  |