Статьи

Тестовое покрытие для ваших корпоративных компонентов. Запуск Eclemma с GlassFish 3.1

Вы когда-нибудь боролись с процентом тестового покрытия в ваших проектах? Для всех проектов разработки важно не только иметь хорошее представление о вашем общем охвате тестированием, но и иметь под рукой какой-то инструмент для подбора эластичного номера для каждой итерации, которую вы выполняете.
Если вы работаете с проектами Java EE, вы должны найти способ проверить покрытие для ваших bean-компонентов, управляемых контейнером. Это краткое руководство по использованию Eclemma с Eclipse и встраиваемым контейнером GlassFish для получения информации о покрытии ваших EJB.

Подготовка
Получите себе последнюю сборку Eclipse Helios (я использую Eclipse IDE для разработчиков Java EE) и установите любые дополнительные компоненты (например, m2eclipse, серверные адаптеры GlassFish), которые могут вам понадобиться. Не забудьте приобрести последнюю версию GlassFish Server 3.1 с открытым исходным кодом (полная платформа). Я собираюсь продемонстрировать использование Embedded Container двумя различными способами, так что у вас также должен быть Maven. Последний шаг — установить Eclemma в вашу версию Eclipse.

Что все это вокруг?
Если вы начнете поискать встраиваемую EJB glassfish и так далее, вы получите несколько решений. Некоторые упоминают API контейнера EJB 3.1, некоторые — встроенный GlassFish, некоторые говорят о плагине Embedded Maven. Итак, самое первое, что я хотел бы сделать, это рассказать вам о параметрах, которые вам нужны для запуска корпоративных бинов во встроенном режиме.

GlassFish Server 3.1 Встроенный сервер
Полный сервер GlassFish имеет встраиваемый API. Они попадают в разные категории. API верхнего уровня (org.glassfish.embeddable), которые предоставляют классы и интерфейсы, необходимые для встраивания GlassFish и выполнения операций жизненного цикла, развертывания приложений и конфигурации времени выполнения. API-интерфейсы Scattered Archive (org.glassfish.embeddable.archive), которые содержат абстракцию для разбросанного архива Java EE. API веб-контейнера (org.glassfish.embebdable.web, org.glassfish.embeddable.web.config), которые предоставляют классы и интерфейсы, необходимые для программной настройки встроенного веб-контейнера и создания контекстов, виртуальных серверов и веб-прослушивателей. Расширенные возможности подключения или интерфейсы поставщиков услуг (org.glassfish.embeddable.spi) для добавления пользовательской среды выполнения GlassFish. Последняя часть — это API-интерфейсы EJB-контейнера (javax.ejb.embeddable), которые являются частью спецификации EJB 3.1, встраиваемая загрузка контейнера. Все эти API помогают полностью интегрировать сервер GlassFish в вашу собственную инфраструктуру. Если вы хотите использовать полный встроенный сервер, вам нужно добавить в свой проект либо полный, либо веб-файл jar.

<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1</version>
</dependency>

или же

<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-web</artifactId>
<version>3.1</version>
</dependency>

API контейнера EJB 3.1
Начиная с Java EE 6 и EJB 3.1 у вас есть новый API для запуска ваших компонентов вне контейнера ( GlassFish 3.1 документы). Встраиваемый API EJB 3.1 поддерживает все функции EJB 3.1 Lite с добавлением службы таймера EJB и тестированием модулей EJB, упакованных в файл WAR. Для модулей EJB в файле WAR (или в разобранном каталоге), если в веб-приложении есть один модуль EJB и в пути к классам нет других модулей EJB, эти записи (библиотеки) игнорируются. Если есть другие модули EJB, создается временный файл EAR. Для тестирования модулей EJB в файле WAR клиентский код должен использовать модули EJB с интерфейсами или без аннотаций. Эти EJB-модули не являются частью пути к классам и не могут быть загружены загрузчиком классов клиента. Этот API в основном полезен для внешнего тестирования ваших EJB-контейнеров. Если вы хотите использовать только этот контейнерный API, вам просто нужно добавить% AS-INSTALL% / glassfish / lib / embedded / glassfish-embedded-static-shell.банку из вашей существующей (!) установки GlassFish в ваш проект.

Maven Plugin GlassFish Maven Glassfish Плагин является Maven2 плагин позволяет осуществлять управление Glassfish доменов и развертывание компонентов внутри сборки жизненного цикла Maven. Он инкапсулирует атрибуты конфигурации и развертывания домена в конфигурации сборки для более быстрого цикла интеграции разработки и упрощенного управления непрерывным интеграционным тестированием компонентов, предназначенных для развертывания в контейнерах Glassfish V2 и более поздних JavaEE. Насколько я знаю, этот плагин просто облегчает использование доступных команд asadmin для управления установкой сервера GlassFish. Начало работы с Maven и API-интерфейсом для встроенного сервера GlassFish Server 3.1


На этом первом шаге я собираюсь продемонстрировать использование встроенного API сервера. Создайте новый проект модуля maven ejb и добавьте в него полнопрофильную зависимость:

<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1</version>
</dependency>

Реализуйте простой ServiceBean с некоторыми методами. Должно быть больше, чем один, потому что я хотел бы, чтобы вы тоже увидели некоторые не покрытые методы;)

// ... imports
@Stateless
public class SimpleService {
// ...
public String saySomething(String sometext) {
LOGGER.log(Level.INFO, "sometext: {0}", sometext);
return "hello from " + sometext;
}

Теперь реализуйте свой Testclass. Давайте назовем это SimpleServiceTest. Настоящее волшебство происходит в @BeforeClass и @AfterClass.

// ... imports
@BeforeClass
public static void setUpBeforeClass() throws Exception {
// Define GlassFish and add target/classes as deploy folder
GlassFish glassfish = GlassFishRuntime.bootstrap().newGlassFish();
glassfish.start();
Deployer deployer = glassfish.getDeployer();
URI uri = new File("target/classes").toURI();
deployer.deploy(uri);
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
// Stop GlassFish
glassfish.stop();
glassfish.dispose();

Осталось только реализовать тест.

@Test
public void testSaySomething() {
try {
InitialContext ic = new InitialContext();
SayHelloBean simpleService = (SayHelloBean) ic
.lookup("java:global/classes/SayHelloBean!net.eisele.coverage.ejb.SayHelloBean");
assertNotNull(simpleService);
String response = simpleService.saySomething("Markus");
assertEquals("hello from Markus", response);
} catch (NamingException e) {
throw new AssertionError(e);
}
}

Не забудьте использовать соответствующее имя JNDI. Каждый найденный EJB-компонент развертывается на встроенном сервере, а имя JNDI создается с использованием префикса java: global / classes, за которым следует простое имя класса EJB (вы также можете использовать соответствующее имя Global JNDI, как в примере выше). ). Если вы теперь запустите свой тест с «Coverage As …> JUnit Test (Alt + Shift + E, T)», вы получите новое представление Coverage в Eclipse, которое показывает что-то вроде этого:

Ваш код выделяется в соответствии с отчетом о покрытии также:

Большой! Вы сделали. Удачного кодирования. Теперь давайте посмотрим на следующий вариант.

Начало работы с ANT и контейнерным API EJB 3.1

Создайте новый проект EJB с помощью eclipse и добавьте% AS-INSTALL% / glassfish / lib / embedded / glassfish-embedded-static-shell.jar в путь сборки. Не забудьте удалить время выполнения сервера, назначенное вами при создании проекта. Опять же: создайте свой EJB (ы) и тестовый набор. И снова, настоящее волшебство происходит в @BeforeClass и @AfterClass.

// ... imports

private static EJBContainer ejbContainer;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File("target/classes"));
ejbContainer = EJBContainer.createEJBContainer(properties);
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
ejbContainer.close();
}

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

@Test
public void testSaySomething() {
try {
InitialContext ctx = new InitialContext();
SayHelloBean simpleService = (SayHelloBean) ctx .lookup("java:global/classes/SayHelloBean!net.eisele.coverage.ejb.SayHelloBean");
assertNotNull(simpleService);
String response = simpleService.sayHello("Markus");
assertEquals("Hello: Markus", response);
} catch (NamingException e) {
throw new AssertionError(e);
}
}

Если вы сейчас запускаете свой тест JUnit «Выполнить как …> Тест JUnit (Alt + Shift + X, T), все работает нормально. Запуск этого с Eclemma Coverage не работает. Вы получаете неприятное исключение javax.naming.NamingException, потому что поиск не удался. Если вы просматриваете вывод консоли, вы видите, что EJB-компоненты связаны с очень странными именами:

java:global/ejb-app7860127669114899398/23c86a3f57efddcfe9c95749beab5a21/SayHelloBean, 

Чтобы предотвратить это, вы должны изменить конфигурацию покрытия для вашего теста на «Инструментарий на месте».

EclEmma старается не трогать содержание вашего проекта. Поэтому файлы классов обычно инструментируются вне вашего проекта во временной папке. Это как раз то, откуда приходят необычные имена JNDI. Инструментарий на месте изменит ваши файлы классов. Инструментированные файлы классов не могут использоваться с режимами запуска, отличными от Coverage. Поэтому после запуска покрытия с использованием инструментов на месте требуется чистая сборка.

Помимо этого изменения, все работает точно так же, как в примере с maven.

Заключение

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

Ссылки и чтения

Использование EJBContainer API с или без Maven (но с GlassFish v3) модульное

тестирование EJB и JPA с Embeddable GlassFish

GlassFish >> Embedded

Краткое введение в Embeddability GlassFish Open Source Edition 3.1

Обзор встроенных API GlassFish (JavaDoc)

Дополнительные исходные примеры использования GF Embedded (java.net svn)

Изменение уровней журнала во встроенном GlassFish

 

От  http://blog.eisele.net/2011/04/test-coverage-for-your-enterprise-beans.html