У разработчиков Java наконец-то появился шанс получить мощный инструмент тестирования JEE с открытым исходным кодом от JBoss.
Arquillian — это расширение для тестовых сред, таких как JUnit и TestNG, которые можно использовать для проверки поведения управляемых bean-компонентов, корпоративных bean-компонентов или POJO, использующих корпоративные сервисы. Версия 1.0.0 альфа 1 версии Arquillian была только что выпущена, и JBoss говорит, что они готовы использовать ее для тестирования Seam 3 даже на этой ранней стадии. Arquillian призван сделать интеграционное тестирование таким же простым, как модульное тестирование. Здесь мы приведем несколько примеров использования Arquillian в действии и рассмотрим все функции, которые будут добавлены в следующих выпусках. Существует также
вводная статья по Arquillian, которая дает
хороший обзоро том, что технология может сделать.
Разработчики могут создавать и выполнять тесты Arquillian во многом как обычный модульный тест, а среды тестирования можно легко менять или использовать последовательно. С помощью
API ShrinkWrap группы тестов упаковываются в архивы Java EE, что позволяет детально контролировать тестируемые ресурсы. Затем тестовые архивы могут быть развернуты и выполнены в подключаемом контейнере Java EE (удаленном или встроенном) или в загрузочной среде CDI (контексты и внедрение зависимостей {JSR 299}). Наконец, коммуникация в стиле RPC между средой и исполнителем тестов согласовывает, какие тесты выполняются, и возвращает результаты. Давайте рассмотрим
два
примера использования Arquillian в JBoss:
Тестирование модуля JMS для шва 3
В этом случае Arquillian использовался при тестировании Seam 3, чтобы продемонстрировать, что внедрение ресурсов JMS и пересылка событий CDI в JMS работают правильно. Arquillian — это тестирование в контейнере, поэтому вы можете тестировать его на управляемых ресурсах. Этот тест настроен с использованием Arquillian для запуска в профиле JBoss AS
jboss-remote-60 6.0. JUnit 4 — это среда тестирования, а JBoss Messaging — поставщик JMS. JBoss Messaging позволяет связывать дескрипторы развертываний для мест назначения с развертываниями, что означает, что вы можете настроить контрольный пример для внедрения ресурсов JMS полностью в Arquillian. В этом примере также будет проверяться развертывание адресатов JBoss Messaging через Arquillian.
Сначала JBoss настраивает архив развертывания ShrinkWrap, включающий в себя переносимое расширение JMA, необходимые классы и конфигурацию назначения темы для тестирования простого внедрения назначения:
@RunWith(Arquillian.class)
public class JmsResourceInjectionTest {
@Deployment
public static Archive<?> createTestDeployment()
{
return Archives.create("test.jar", JavaArchive.class)
.addPackages(false, Seam3JmsExtension.class.getPackage(), SimpleInjectionTest.class.getPackage())
.addManifestResource(new ByteArrayAsset(new byte[0]), ArchivePaths.create("beans.xml"))
// Register the portable extension
.addServiceProvider(Extension.class, Seam3JmsExtension.class)
// Include JBoss Messaging topic configuration
.addManifestResource("topic_T-service.xml");
}
}
Это конфиг назначения темы;
topic_T-service.xml :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server>
<mbean xmbean-dd="xmdesc/Topic-xmbean.xml"
name="jboss.messaging.destination:service=Topic,name=T"
code="org.jboss.jms.server.destination.TopicService">
<attribute name="JNDIName">jms/T</attribute>
<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
<depends>jboss.messaging:service=PostOffice</depends>
</mbean>
</server>
Теперь давайте проверим внедрение темы непосредственно в тестовый класс:
@Inject Topic t;
@Test
public void simpleTopicInjection()
{
assertNotNull(t);
assertEquals("T", t.getTopicName());
}
Метод производителя Темы удовлетворяет точке внедрения, беря имя поля, используя его заглавные буквы, добавляя его к строке »
/ jms / «, и затем находит имя (в данном случае
/ jms / T ) в InitialContext JNDI
.
Arquillian особенно полезен, когда он тестирует события CDI, связанные с JMS. Модуль
Seam 3 JMS поддерживает декларативную пересылку событий через JMS. Далее мы рассмотрим тестовый пример, подтверждающий, что события перенаправляются в их правильное место назначения. Во-первых,
MessageConsumer и простое тестовое событие используются для определения того, когда сообщения отправляются через JMS:
@Inject Connection c;
@Inject Session s;
@Inject @Events Topic t;
@Inject Seam3JmsExtension jmsExt;
@Inject Event<String> event;
В этом тестовом примере вы должны зарегистрировать тип события для пересылки через JMS. Затем вы создаете
MessageConsumer для получения событий от предполагаемого места назначения, и, наконец, отправляете событие, а затем проверяете, было ли оно получено в правильном месте назначения.
@Test(timeout=5000)
public void forwardEvent() throws Exception
{
String expected = "test";
jmsExt.register(String.class, t);
MessageConsumer mc = s.createConsumer(t);
c.start();
event.fire(expected);
Message m = mc.receive();
assertNotNull(m);
assertTrue(m instanceof ObjectMessage);
assertEquals(expected, ((ObjectMessage) m).getObject());
}
Узнайте больше о событиях CDI на странице справочной документации по
сварке .
CDI JMX Портативный Тест Расширения
В этом примере
немецкий Escobar использует Arquillian для тестирования
написанного им простого JMX Portable Extension , позволяющего автоматически регистрировать управляемые компоненты с помощью аннотаций. Вот пример используемого расширения:
@ApplicationScoped
@MBean("org.gescobar:type=VisitorCounter")
@Description("Counts the number of visits")
public class VisitorCounter {
@ManagedAttribute(readable=true,writable=true)
private int counter;
public void addVisitor() {
counter++;
}
@ManagedOperation(impact=Impact.ACTION)
public void resetCounter() {
counter = 0;
}
// getter and setters
}
После создания экземпляра компонента он автоматически регистрируется как MBean или MBeanServer. Эскобару нужен был способ проверить его расширение на разных контейнерах, поэтому он использовал Arquillian с TestNG.
Сначала в файл pom.xml добавляются зависимости TestNG и Arquillian:
...
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.10</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-testng</artifactId>
<version>1.0.0.Alpha1</version>
<scope>test</scope>
</dependency>
...
Эскобар создал два профиля в своем pom.xml для JBoss AS 6.0 M2 и Weld SE:
<profiles>
<profile>
<id>jbossas-remote-60</id>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-jbossas-remote-60</artifactId>
<version>1.0.0.Alpha1</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>weld-embedded</id>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-embedded</artifactId>
<version>1.0.0.Alpha1</version>
</dependency>
</dependencies>
</profile>
</profiles>
Чтобы проверить внутри других контейнеров, вы просто создаете больше профилей. Тогда последний шаг — написать тестовый класс. Эскобар должен был сделать две вещи со своим обычным классом TestNG: создать метод с аннотацией @Deployment, который возвращает архив ShrinkWrap, а затем класс должен расширить org.jboss.arquillian.testng.Arquillian.
public class TestAutoRegistration extends Arquillian {
@Deployment
public static JavaArchive createDeployment() {
JavaArchive archive = Archives.create("test.jar", JavaArchive.class)
.addPackage(MBeanFactory.class.getPackage())
.addPackage(CDIMBeanFactory.class.getPackage())
.addPackage(MBeanServerLocator.class.getPackage())
.addClasses(CounterAutoRegisterWithName.class, CounterAutoRegisterNoName.class)
.addManifestResource("services/javax.enterprise.inject.spi.Extension")
.addManifestResource(
new ByteArrayAsset("<beans/>".getBytes()),
Paths.create("beans.xml"));
return archive;
}
@Inject
private CounterAutoRegisterWithName counterWithName;
@Inject
private CounterAutoRegisterNoName counterNoName;
@Test
public void shouldRegisterAnnotatedWithNameMBean() throws Exception {
Assert.assertNotNull(counterWithName);
// the bean is not created until the first call - maybe a bug in weld?
Assert.assertEquals(counterWithName.getCounter(), 0);
MBeanServer mBeanServer = MBeanServerLocator.instance().getmBeanServer();
ObjectName name = new ObjectName("org.gescobar:type=CounterAutoRegisterWithName");
// check we can add the counter
mBeanServer.setAttribute(name, new Attribute("counter", 1));
Assert.assertEquals(counterWithName.getCounter(), 1);
// check we can retrieve the counter
Integer result = (Integer) mBeanServer.getAttribute(name, "counter");
Assert.assertNotNull(result);
// check we can call method without arguments
mBeanServer.invoke(name, "resetCounter", null, null);
Assert.assertEquals(counterWithName.getCounter(), 0);
// check we can call method with arguments
mBeanServer.invoke(name, "resetCounter2", new Object[] { 5 }, new String[] { "java.lang.Integer" });
Assert.assertEquals(counterWithName.getCounter(), 5);
}
@Test
public void shouldRegisterAnnotatedWithNoNameMBean() throws Exception {
Assert.assertNotNull(counterNoName);
Assert.assertEquals(counterNoName.getCounter(), 0);
MBeanServer mBeanServer = MBeanServerLocator.instance().getmBeanServer();
Object result = mBeanServer.getAttribute(new ObjectName("org.gescobar.management.test:type=CounterAutoRegisterNoName"), "counter");
Assert.assertNotNull(result);
}
}
На этом этапе вы запускаете тест, вызывая соответствующие профили, в данном случае Escobar называется:
mvn clean install -Pjbossas-remote-60 и
mvn clean install -Pweld-внедрено . Теперь расширение готово к тестированию на реальных контейнерах. JBoss AS 6 должен быть запущен, если вы используете удаленный профиль, потому что Arquillian не запускает и не останавливает контейнер автоматически, но скоро это сделает.
Скоро
Вот некоторые функции и поддержки, которые вы можете ожидать по мере продвижения Arquillian от альфы к бете и, наконец, к GA:
Больше контейнеров — JBoss планирует добавить поддержку Arquillian для GlassFish v3 в качестве удаленного контейнера (уже поддерживает его как встроенный контейнер) , Jetty, Tomcat, Resin и Felix OSGi. Весна также приветствуется, если они заинтересованы.
Интеграция со сторонними разработчиками — планируется поддержка многих других сред тестирования, включая JSFUnit, Selenium и «
Mock JSF Objects ».
Соглашение по конфигурации — чтобы упростить создание
микро развертываний и ускорить разработку тестов, JBoss добавит поддержку общих соглашений, которые можно использовать во всех ваших тестовых примерах.
Контролируемые ресурсы — для создания
InitialContext контейнеру иногда требуются определенные параметры конфигурации. Если тестовый пример должен иметь дело с этим явно, он возлагает бремя переносимости контейнера обратно на автора тестового примера. Arquillian предоставит точку расширения для добавления созданных / управляемых ресурсов Arquillian:
// auto creation of InitialContext based on running container, remote or local.
@ArquillianResource
private InitialContext context;
// auto creation of URL to a specific deployed Servlet, including http port/ip etc.
@ArquillianResource(MyServlet.class)
private URL myServletURL;
// the bundle context of a deployed osgi bundle
@ArquillianResource
private BundleContext context;
Embedded AS — поддержка JBoss Embedded AS не была готова к выпуску альфы 1, но она определенно находится на пути. Встроенный AS позволяет вам запускать JBoss AS внутри той же JVM при запуске теста, что упрощает отладку теста.
Инструменты сборки — сейчас Arquillian поставляется только с поддержкой Maven, но поддержка Ant и Gradle запланирована на будущие выпуски.
Режим локального запуска — в Arquillian будет добавлен режим локального запуска, так что вам не обязательно запускать тестовый пример внутри самого контейнера. В режиме локального запуска тесты будут контролировать развертывание, но они не будут развернуты как его часть. Это, например, позволит тестировать страницы JSF или RMI.
Один тест, управляющий несколькими развертываниями— Это позволит вам упаковать другие компоненты как часть одного и того же развертывания. Например, Arquillian сможет проверить взаимодействие между двумя веб-приложениями.
Метод Argument Injection Support — Arquillian alpha 1 поддерживает только инъекцию поля. Alpha 2 будет иметь расширенный
TestEnricher SPI, чтобы добавить поддержку для инъекции аргументов метода:
@Test
public void shouldWithdrawFromAccount(@EJB AccountManager manager) throws Exception
{
...
}
Перехватчики метода тестирования — SPI метода перехватчика теста добавит поддержку транзакций:
@Test
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void shouldWithdrawFromAccount(@EJB AccountManager manager) throws Exception
{
...
}
Логотип — это, наверное, самая важная часть любого проекта. Название проекта звучит довольно привлекательно, теперь им нужен крутой логотип. Это тоже уже в пути.
JBoss также заменит текущее ядро CDI TCK на Arquillian — скорее всего, для версии 1.1 TCK.