В последнее время у меня была возможность использовать библиотеку OSGi-JAX-RS-Connector, написанную моим дорогим товарищем Хольгером Стаудхером . Соединитель позволяет легко публиковать ресурсы, регистрируя аннотированные типы @Path в качестве сервисов OSGi — что на самом деле работает довольно хорошо.
Хотя для меня естественно писать тесты классов обслуживания, основанные на простых тестах JUnit , также очень важно предоставить дополнительные интеграционные тесты. Эти тесты позволяют проверить доступность и функциональность таких сервисов во время выполнения. Чтобы обеспечить последнее, я использовал другого маленького помощника, написанного Holger — restfuse, который является расширением JUnit для автоматизированных тестов HTTP / REST.
Сценарий выглядит примерно так:
Сервис
1
2
3
4
5
6
7
8
9
|
@Path ( '/message' ) public class SampleService { @GET @Produces ( MediaType.TEXT_PLAIN ) public String getMessage() { return 'Hello World' ; } } |
Контрольный пример JUnit
01
02
03
04
05
06
07
08
09
10
11
|
public class SampleServiceTest { @Test public void testGetMessage() { SampleService service = new SampleService(); String message = service.getMessage(); assertEquals( 'Hello World' , message ); } } |
Служба регистрации
1
2
3
4
5
6
7
8
9
|
<? xml version = '1.0' encoding = 'UTF-8' ?> < scr:component name = 'SampleService' > < implementation class = 'sample.SampleService' /> < service > < provide interface = 'sample.SampleService' /> </ service > </ scr:component > |
Интеграционный тест restfuse
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
@RunWith ( HttpJUnitRunner. class ) public class SampleServiceHttpTest { @Rule public Destination destination @Context private Response response; @HttpTest ( method = Method.GET, path = '/services/message' ) public void checkMessage() { String body = response.getBody( String. class ); assertOk( response ); assertEquals( MediaType.TEXT_PLAIN, response.getType() ); assertEquals( 'HelloWorld' , body ); } } |
Бегущий сервис
Хотя все это было довольно просто, меня это как-то беспокоило, что для запуска интеграционных тестов локально требовалось сначала запустить сервер, прежде чем я смог выполнить интеграционный тест. Занимаясь поставленной задачей, я часто забывал запустить сервер и сталкивался с таймаутами соединения или чем-то подобным.
Но я нашел решение для этого, используя конфигурацию запуска PDE JUnit , потому что такая конфигурация может быть настроена для запуска сервера в процессе, который запускает тесты.
Для этого создайте и выберите набор тестов, который содержит все интеграционные тесты для запуска 1 …
… после этого перейдите на главную вкладку и выберите режим без головы …
… И, наконец, что не менее важно, настройте программные аргументы, используемые сервером, которые в нашем случае в основном касаются определения порта.
Выбор комплекта на вкладке «Плагины» содержит те же комплекты, что и в конфигурации запуска osgi, которая используется для запуска автономного сервера, а также комплекты JUnit-, PDE JUnit-, restfuse-bundles и их зависимости. Выбранный набор тестов может выглядеть так:
01
02
03
04
05
06
07
08
09
10
|
@RunWith ( Suite. class ) @SuiteClasses ( { SampleServiceHttpTest. class } ) public class AllRestApiIntegrationTestSuite { public static String BASE_URL + System.getProperty( 'org.osgi.service.http.port' ); } |
Единственная необычная вещь здесь — это определение константы BASE_URL. Как упоминалось выше, порт сервера тестового прогона указывается в качестве аргумента программы в конфигурации запуска. Но тесты restfuse должны предоставлять порт во время определения правила назначения. Использование описанного выше подхода позволяет изменить порт в конфигурации, не влияя на тесты. Просто используйте константу в качестве параметра в определении, как показано в следующем фрагменте 2 3 .
1
2
3
|
@Rule public Destination destination = new Destination( BASE_URL ); |
Эта простая установка сработала очень хорошо и улучшила мой рабочий процесс при проведении интеграционных тестов локально А сохранение конфигурации запуска в общем проекте позволяет вашим коллегам по команде повторно использовать ее.
Так что это на сегодня, и, как всегда, обратная связь высоко ценится. Кстати, Хольгер пообещал мне написать пост о том, как интегрировать описанные выше вещи в сборку на основе maven / tycho 4 — так что следите за обновлениями
- Конечно, вы также можете использовать возможность запуска всех тестов выбранного проекта, пакета или папки с исходным кодом, но для наших целей здесь достаточно использовать подход с использованием набора и запустить один тестовый пример.
- Вы, вероятно, предоставили бы отдельный класс для определения константы в реальном сценарии, чтобы избежать привязки тестов к набору. Я пропустил это здесь для упрощения.
- Обратите внимание, что BASE_URL включен с использованием статического импорта для лучшей читаемости фрагмента
- Хольгер сдержал свое обещание, см .: http://eclipsesource.com/blogs/2012/09/11/running-httprest-integration-tests-in-an-eclipse-tycho-build/
Справка: Эффективное проведение интеграционных тестов HTTP / REST в Eclipse от нашего партнера по JCG Фрэнка Аппеля из блога Code Affine .