Arquillian permite crear tests de integración con servidores/contenedores web y JEE como WildFly (o Tomcat), de forma bastante sencilla.
Para trabajar con un servidor, Arquillian usa adaptadores de contenedor, que permiten arrancar y parar los contenedores. Estos pueden ser de tres tipos: embebidos, gestionados, y remotos (embedded, managed y remote, a partir de ahora).
Para este Hola mundo usaremos el adaptador embedded, y dejaremos para otro artículo la discusión de qué ventajas e inconvenientes tiene cada tipo de adaptador y cuándo usar cada uno.
1. Configuración de dependencias
Para compilar los tests necesitaremos JUnit y Arquillian: con tan solo incluir junit:junit:4.11
y org.jboss.arquillian.junit:arquillian-junit-container:1.1.8.Final
en build.gradle
se incluirán todos los demás jars necesarios, especialment las dependencias de Arquillian.
Para ejecutar los tests, debemos incluir un adaptador de contenedor de WildFly, que Arquillian usará para arrancar y parar el contenedor contra el que se ejecutará el test. Como usaremos el contenedor embedded de WildFly, debemos incluir org.wildfly:wildfly-arquillian-container-embedded:8.2.0.Final
en la lista de dependencias.
Por último, para que Gradle pueda encontrar algunas de estas dependencias deberemos añadir un repositorio de JBoss a nuestro build.gradle
, que una vez hecho todo esto quedará como sigue:
apply plugin: 'java'
sourceCompatibility = 1.6
repositories {
mavenCentral()
maven {
url "http://repository.jboss.org/nexus/content/groups/public-jboss"
}
}
dependencies {
compile 'javax:javaee-api:6.0'
testCompile 'junit:junit:4.11',
'org.jboss.arquillian.junit:arquillian-junit-container:1.1.8.Final'
testRuntime 'org.wildfly:wildfly-arquillian-container-embedded:8.2.0.Final'
}
test {
// Si no se especifica el log manager con el adaptador embedded de WildFly 8.2,
// no arrancara correctamente
systemProperties 'java.util.logging.manager': 'org.jboss.logmanager.LogManager'
}
2. Código
Para demostrar cómo implementar y ejecutar tests sencillos crearemos un stateless session bean, MyStatelessEjb
, que simplemente suma dos números:
import javax.ejb.Stateless;
@Stateless
public class MyStatelessEjb {
public int sum(int a, int b) {
return a + b;
}
}
Para hacer un test JUnit con Arquillian necesitaremos un runner de JUnit especial, incluido con Arquillian, para lo que anotaremos la clase de test con @RunWith(Arquillian.class)
.
También debemos especificar la configuración básica de la aplicación, para que el test se pueda ejecutar en el contexto adecuado. Debemos indicar dónde están los .class necesarios, si vamos a crear un war u otra cosa, quizá incluir un archivo de configuración como persistence.xml
, etc.
Para ello se debe crear un método anotado con @Deployment
, que utilizará la clase ShrinkWrap
para llevar a cabo toda esta tarea de configuración.
El código resultante para hacer el test será como sigue:
@RunWith(Arquillian.class)
public class MyStatelessEjbTest {
@EJB
private MyStatelessEjb ejb;
@Deployment
public static Archive<?> createTestArchive() {
return ShrinkWrap.create(WebArchive.class)
.addPackage(MyStatelessEjb.class.getPackage());
}
@Test
public void testSum() {
Assert.assertEquals(5, ejb.sum(6,-1));
}
}
Por lo demás, los tests son tests JUnit normales y corrientes, como se puede ver con testSum
. Nótese que este test usa nuestro bean, que se ha inyectado en el test con @EJB
, y que el propio contenedor WildFly gestiona.
3. Configuración de Runtime
Llegados a este punto, la aplicación compilará, pero aún es necesario dar unos pasos extra para que la aplicación arranque y podamos ejecutar los tests.
Las librerías adicionales necesarias en tiempo de ejecución ya las hemos incluido en un paso anterior, pero aún debemos configurar Arquillian. Esto se hace mediante arquillian.xml
, que ubicaremos en el directorio src/test/resources
del proyecto. Quedará como sigue:
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="jboss-embedded" default="true">
<configuration>
<property name="jbossHome">/home/pagdev/pagde/tool/wildfly-8.2.0.Final</property>
<property name="modulePath">/home/pagdev/pagde/tool/wildfly-8.2.0.Final/modules</property>
<property name="serverConfig">standalone-full.xml</property>
</configuration>
</container>
</arquillian>
Aquí usamos la propiedad jbossHome
, requerida, para indicar cuál es el directorio donde se halla JBoss (como JBOSS_HOME
).
Esta versión del adaptador también requiere que se le pase el parámetro modulePath
, que es donde se encuentran los módulos utilizables de JBoss. Por defecto están en el subdirectorio modules
en JBoss. Es curioso que este parámetro sea obligatorio, dado que podrían utilizar un valor por defecto sin problemas.
También he añadido el parámetro serverConfig
, que nos permite especificar qué configuración de servidor vamos a utilizar, y que no es requerido.
4. Ejecutar tests
Desafortunadamente necesitamos un pequeño workaround para un bug del adaptador embedded. Es necesario pasarle al contenedor WildFly arrancado por Arquillian el parámetro java.util.logging.manager
, para el que simplemente utilizaremos el LogManager
por defecto de WildFly. Esto es lo que hace el siguiente fragmento de build.gradle
:
test {
systemProperties 'java.util.logging.manager':
'org.jboss.logmanager.LogManager'
}
Una alternativa a esto sería llamar a gradle desde la línea de comando pasándole ese parámetro. Para lanzar todos los tests del proyecto, por ejemplo, tendríamos la siguiente línea de comandos:
gradle test -Djava.util.logging.manager=org.jboss.logmanager.LogManager --tests *Test
Con la configuración actual de build.gradle
, podemos lanzar el test con
gradle test --tests *Test
Por otro lado, si ejecutamos los tests desde Eclipse y no usando Gradle desde la línea de comandos, habrá que indicarle al launcher correspondiente que pase a la VM el parámetro -Djava.util.logging.manager=org.jboss.logmanager.LogManager
.
Si queremos ejecutar estos tests desde la línea de comandos, y depurarlos con Eclipse, vale la pena consultar este otro artículo.
Software utilizado
Esto ha sido probado con WildFly 8.2 y Arquillian 1.1.8, usando Gradle 2.3.