Tutoriel Maven – Tests unitaires Java

Objectif: Ce tutoriel Maven concerne la mise en place de test unitaire java avec cet outil. Par défaut, à la génération d’un nouveau projet, Maven met en place tout ce qu’il faut pour intégrer un test unitaire java. Il s’agit de la branche test de l’arborescence créée, cf. l’article Tutoriel Maven 3 – partie 2. Dans ce tutoriel Maven on verra comment mettre en place ce test unitaire java, comment le contourner en cas de besoin et l’intérêt de cette fonctionnalité dans le processus de développement de logiciels. Pré-requis: le JDK est installé, cf. l’article: Installer Java sur Ubuntu ou compatible et Maven 3 est installé cf. l’artice: Tutoriel Maven 3 – partie 1

1. Maven test unitaire Java est mis en place par défaut à la génération du projet

mvn archetype:generate -DgroupId=com.example.calculateur \
    -DartifactId=calculteur -Dversion=1.0 -Dpackage=com.example.calculateur \
    -DinteractiveMode=false
ls calculateur/src/test/java/com/exemple/calculateur/
AppTest.java
La classe AppTest.java a été générée pour contenir le code des tests. La dépendance au framework JUnit a été rajoutée dans le fichier pom.xml
.....
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
</dependencies>
.....

2. Simuler une erreur de test unitaire Java

Dans le code de la classe AppTest.java, repérer:
public void testApp()
{
   assertTrue( true );
}
Et modifier en:
public void testApp()
{
   assertTrue( false );
}
Après cela si on lance la reconstruction de l’application, l’opération échoue à cause de test non concluant.
mvn clean package
..
..
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.exemple.calculateur.AppTest
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.46 sec <<< FAILURE!

Results :

Failed tests:   testApp(com.exemple.calculateur.AppTest)

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

3. Ajouter les fonctions de calcul à l’application

Ajouter une classe qui se charge des calculs: Calc.java et activer l’appel au calcul dans App.java
package com.exemple.calculateur;
public class Calc
{
  private int getInt(String s) {
    int resultat = -1;
    try {
      resultat = Integer.parseInt(s);
    }
    catch (NumberFormatException e) {
      resultat = -1;
    }
    finally {
      return resultat;
    }
  }
  public int somme(String s1, String s2)
  {
    int i1 = getInt(s1);
    int i2 = getInt(s2);
    int resultat = i1 + i2;
    return resultat;
  }
  public int multiplication(String m1, String m2)
  {
    int i1 = getInt(m1);
    int i2 = getInt(m2);
    int resultat = i1 * i2;
    return resultat;
  }
}
// Dans App.java
public static void main( String[] args )
{
  if (args.length != 3) {
    System.out.println("Opération non supportée.");
    System.exit(1);
  }
  String operation = args[1];
  Calc calc = new Calc();
  int resultat = -1;
  if (operation.equalsIgnoreCase("+")) {
    resultat = calc.somme(args[0], args[2]);
  } else if (operation.equalsIgnoreCase("x")) {
    resultat = calc.multiplication(args[0], args[2]);
  }
  if (resulat >= 0) {
    System.out.println("Résultat: " + resultat);
  } else System.out.println("Opération non supportée");
}
Ce code a été écrit pour répondre au cahier des charges suivant:
  1. Le calculateur peut effectuer les opérations d’addition et de multiplication.
  2. Les opérations ne portent que sur des nombres entiers positifs ou nul.
  3. On passe trois arguments au calculateur, dans l’ordre: 1er opérande, opération, 2eme opérande.
  4. En cas d’erreur d’utilisation le calculateur répond par le message “Opération non supportée”.

4. Ajouter le test unitaire Java en conformité avec le cahier des charges

Ce test doit contrôler le fonctionnement des méthodes de la classe Calc qui effectue le calcul et constitue le cœur de cette application. Commençons par la méthode Calc.somme(String s1, String s2). Dans AppTest.java on va modifier le code, cette fois pour inclure les tests.
public void testApp()
{
  Calc calc = new Calc();
  assertEquals(calc.somme("321", "425"), 746);
  assertTrue(calc.somme("abc", "cba") < 0);
  assertTrue(calc.somme("abc", "653") < 0);
  assertTrue(calc.somme("-145", "153") < 0);
}
A la construction de l’application le troisième test échoue. En révisant le code de la classe Calc, on s’aperçoit de l’erreur et on corrige le code de la méthode Calc.somme(String s1, String s2)
public int somme(String s1, String s2)
{
  int resultat = -1;
  int i1 = getInt(s1);
  int i2 = getInt(s2);
  if ((i1 >= 0) && (i2 >= 0)) resultat = i1 + i2;
  return resultat;
}
Après cette correction, la construction de l’application se fait sans échec. Vous pouvez vous exercer en mettant en place les tests pour la deuxième méthode de multiplication.

5. Désactiver le test unitaire Java

Dans certains cas, on pourrais avoir besoin de désactiver la phase de test afin de forcer la construction de l’application. Cela peut se faire de deux façons.

5.1. En ligne de commande

mvn -Dmaven.test.skip=true package

5.2. En modifiant le fichier pom.xml

Dans le fichier pom.xml du projet, ajouter la référence au plug-in surefire. Remarquer le paramètre: <skipTests>true</skipTests>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.18.1</version>
  <configuration>
    <skipTests>true</skipTests>
  </configuration>
</plugin>
]]>