Tests HTTP avec Arquillian

Pour commencer 2013 en beauté, rien de mieux que de finir l’année avec une mission pleine de nouveaux challenges et de nouvelles technos : Cassandra, Play!, EJB3 (!) et Arquillian.

Arquillian est un outil qui permet de faire des tests d’intégration. Il permet notamment de construire programmatiquement des jar, war et ear très simplement et de déployer ces pseudos-livrables dans un serveur embarqué.

Étant adepte du TDD, quand on me demande de faire un service web, j’aime me mettre à la place du client web et manger du HTTP afin de vérifier le contenu des retours mais aussi les entêtes, les E-Tag, la compression etc… C’est que nous permet de faire Rest-Assured. Nous allons justement voir dans cet article comment tester un service web par la couche HTTP en se servant d’Arquillian pour déployer le service de manière embarqué.

Dans cet exemple, nous utilisons le serveur glassfish embedded. Nous testons un service REST permettant de consulter des logs applicatifs. Ainsi on souhaite vérifier que la requête HTTP : « GET http://localhost:8181/logs?severity=error » retourne bien un code HTTP 200 OK.

Le Test

Voici le code test que nous souhaitons faire :

import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.parsing.Parser;
import com.jayway.restassured.specification.ResponseSpecification;
import static com.jayway.restassured.RestAssured.expect;
import static com.jayway.restassured.RestAssured.given;

@RunWith(Arquillian.class)
public class SomeArquillianTest{

  @Test
  @RunAsClient
  public void simpleClientTestExample(@ArquillianResource URL baseURL) throws IOException {
    expect().statusCode(200).when().get(baseURL.toString() + "logs?severity=ERROR");
  }
}

 

  • @RunWith(Arquillian.class) permet d’utiliser le runner JUnit d’Arquillian.
  • @RunAsClient permet de marquer le test comme étant un test de type « Client ».
  • @ArquillianResource permet d’injecter l’url de base afin de connaitre l’addresse http de l’application.

Créer l’archive à déployer

Afin qu’Arquillian puisse créer une archive de déployement, il suffit de lui spécifier les composants que nous souhaitons tester (classe annotées @Stateless par exemple.) ainsi que le container / Servlet et le fichier web.xml .

import com.sun.jersey.spi.container.servlet.ServletContainer;

import org.jboss.arquillian.container.test.api.Deployment;

import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;

@RunWith(Arquillian.class)
public class simpleClientTestExample {

  @Deployment
  public static Archive<?> createTestArchive() {
    return ShrinkWrap.create(WebArchive.class)
        .addPackages(true, Log.class.getPackage(),
        LogServiceRest.class.getPackage(),
        LogService.class.getPackage())
        .addClass(ServletContainer.class)
        .setWebXML("WEB-INF/web.xml")
  }

Changer le port du serveur embarqué

<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">
  <engine>
    <property name="deploymentExportPath">target/arquillian</property>
  </engine>
  <container default="true" qualifier="glassfish">
    <configuration><property name="bindHttpPort">8181</property></configuration>
  </container>
</arquillian>

 

La pomme

Voici un extrait de ma pomme, à adapter selon votre situation…

<dependencies>
  <dependency>
    <groupId>org.glassfish.main.extras</groupId>
    <artifactId>glassfish-embedded-all</artifactId>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <scope>provided</scope>
  </dependency>
  <!-- Librairies for test -->
  <dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>1.3</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
  </dependency>
  <dependency>
    <groupId>org.jboss.arquillian.junit</groupId>
    <artifactId>arquillian-junit-container</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>com.jayway.restassured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.2</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.1</version>
      <executions>
        <execution>
          <phase>validate</phase>
          <goals>
            <goal>copy</goal>
          </goals>
          <configuration>
            <outputDirectory>${endorsed.dir}</outputDirectory>
            <silent>true</silent>
            <artifactItems>
              <artifactItem>
                <groupId>javax</groupId>
                <artifactId>javaee-endorsed-api</artifactId>
                <version>6.0</version>
                <type>jar</type>
              </artifactItem>
            </artifactItems>
          </configuration>
        </execution>
      </executions>
    </plugin>
 </plugins>
</build>

Et voilà !  Plutôt simple non ?

3 Responses to “Tests HTTP avec Arquillian”

  1. Elim dit :

    Quelles sont les différences entre Jenkins et Arquillian ? Enfin ça y ressemble fortement non ? J’hésite à mettre en place ce système mais pas assez d’expérience pour voir la différence.

  2. Jean-Baptiste dit :

    Jenkins est une application web permettant d’exécuter les builds (ie construire ton projet, passer les tests etc.)

    Arquillian est une librairie java pour faire des tests.

    Les 2 sont très différents et complémentaires.

    Le manque d’expérience est une très mauvaise excuse, qui a déjà démarré quelque chose avec de l’expérience sur la chose ?

  3. Mikael dit :

    Hi,

    Si je comprends bien, Arquillan permet de créer un test unitaire dans un server context (voir plusieurs). Par contre il ne permet pas de mocker les services externes. Peut on le coupler à des framework comme mockito, easymock ou powermock?

Leave a Reply