lunes, 16 de diciembre de 2013

TUTORIAL ARQUILLIAN (I)

¿Qué es Arquillian?


Arquillian es un framework de test que nos permite levantar un contexto embebido CDI y realizar test unitarios y test funcionales en nuestros proyectos.

En nuestras aplicaciones tenemos que probar componentes cuyo ciclo de vida es manejado por el servidor de aplicaciones como EJB´s o JPA´s y nos volvemos locos perdiendo tiempo en crear mocks o probando estos componentes posteriormente en pruebas funcionales cuando deberían tener sus propias pruebas unitarias.

Con Arquillian vamos a poder probar todos estos componentes levantando un contexto CDI, inyectando estos componentes en la propia clase de test que a su vez correrá dentro del contenedor.   



Se integra fácilmente en nuestros proyectos con Maven y funciona con librerías de test como JUnit 4 o TestNG.  Para desplegar desplegables JAVA (JARS, WARS) con las clases disponibles en el contexto CDI utiliza el framework ShrinkWrap.

Escribiendo un test de integración con Arquillian

Para poder ejecutar test con Arquillian vamos a necesitar tener como mínimo Maven instalado y JDK 1.5. Podemos crear un proyecto Maven en Eclipse con el plugin m2e o crearlo manualmente mediante la línea:


mvn archetype:generate -DarchetypeGroupId=net.avh4.mvn.archetype \
-DarchetypeArtifactId=java-1.6-archetype

y  posteriormente importarlo creando los archivos con el goal eclipse:eclipse.


Una vez que hemos creado el proyecto nos debería aparecer algo como lo siguiente:



En el pom nos debería aparecer lo básico, el plugin para compilar con la JDK 1.6 y la librería de JUnit para los test unitarios:

<build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12</version>
            </plugin>
        </plugins>
    </build>
<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
</dependency>
<dependency>
            <groupId>org.jboss.spec</groupId>
            <artifactId>jboss-javaee-6.0</artifactId>
            <version>1.0.0.Final</version>
            <type>pom</type>
            <scope>provided</scope>
</dependency>


A continuación creamos en nuestro proyecto un componente el cual utilizaremos para probar  la inyección de dependencias en un servidor embebido (JBOSS, GLASSFISH…):

public class Greeter {

    private PhraseBuilder phraseBuilder;

    @Inject
    public Greeter(PhraseBuilder phraseBuilder) {
        this.phraseBuilder = phraseBuilder;
    }

    public void greet(PrintStream to, String name) {
        to.println(createGreeting(name));
    }

    public String createGreeting(String name) {
        return phraseBuilder.buildPhrase("hello", name);
    }
}

Para añadir el soporte de Arquillian a nuestro proyecto añadimos primero las dependencias transitivas de Arquillian dentro de la sección dependencyManagement:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.0.3.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


A continuación añadimos la dependencia que nos servirá de puente para utilizar Arquillian con JUnit 4, que añadirá también las dependencias de ShrinkWrap para desplegar artefactos Java. En este punto hay que decir que tenemos la opción de utilizar Arquillian con otras librerías de pruebas como el framework TestNG:

  <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
  </dependency>


Una vez que hacemos esto ya podemos escribir nuestro primer test unitario. Para ello creamos una clase de Test, inyectamos nuestro componente con las anotaciones CDI, creamos y desplegamos con ShrinkWrap un JAR con nuestra clase y un archivo beans.xml vacío pero necesario para que funcione todo correctamente por la especificación JEE 6


El código del test unitario es el siguiente:

@RunWith(Arquillian.class)
public class GreeterTest {

    @Deployment
    public static JavaArchive createDeployment() {
        JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
            .addClasses(Greeter.class, PhraseBuilder.class)
            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");     
        return jar;
    }

    @Inject
    Greeter greeter;

    @Test
    public void should_create_greeting() {
        Assert.assertEquals("Hello, Earthling!",
            greeter.createGreeting("Earthling"));
        greeter.greet(System.out, "Earthling");
    }
}

·         @RunWith: el test corre bajo el soporte de Arquillian
·         @Deployment: anotación sobre el método que crea el desplegable Java
·         @Inject: para instanciar nuestro componente en la clase de test
·         @Test: anotación para indicar qué es un método de test


Ahora viene lo mejor. Estos test unitarios deben correr bajo un contenedor pero, ¿Cuál?  Pues podremos elegir varios contenedores compatibles con el modelo de programación de nuestra prueba siempre y cuando exista un adaptador en Arquillian con este contenedor. Para el test de inyección de CDI podremos utilizar JBoss 7, Glassfish 3 o Weld (implemenación de referencia de CDI). Arquillian también permite ejecutar los test con un servidor real sin cambiar una sola línea de código (previamente a las pruebas deberemos tener levantado dicho servidor). Si utilizamos por ejemplo Glassfish 3 deberemos añadir las siguientes dependencias:

<dependency>
                    <groupId>org.jboss.arquillian.container</groupId>
                    <artifactId>arquillian-glassfish-embedded-3.1</artifactId>
                    <version>1.0.0.CR3</version>
                    <scope>test</scope>
                </dependency>
                <dependency>
                    <groupId>org.glassfish.main.extras</groupId>
                    <artifactId>glassfish-embedded-all</artifactId>
                    <version>3.1.2</version>
                    <scope>provided</scope>
                </dependency>

Para resumir el tema de las dependencias están:

·       La dependencia de integración de Arquillian y JUnit.:

<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>


·       La dependencia de Arquillian para el contenedor:

<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
       <version>1.0.0.CR3</version>
      <scope>test</scope>
</dependency>

·         Y el ambiente de ejecución del contenedor:

<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
<scope>provided</scope>
</dependency>


Finalmente probamos nuestro test en Eclipse ejecutándolo como un test unitario normal: Run As Junit Test.

No hay comentarios:

Publicar un comentario en la entrada