Continuous Testing
Les tests unitaires
Définition
Un test est un bout de code qui provoque l'éxecution d'un autre bout de code et qui en analyse le résultat. Le premier bout de code est donc le test qui a été écrit, le second est le programme ou la fonction à tester. Le résultat d'un test est valide ou invalide.
L'intérêt des tests unitaires
Plusieurs raisons pour écrire des tests unitaires :
- Programmer efficacement : on parle d'éfficacité puisque écrire des tests signifie vérifier que l'on répond correctement aux attentes du programme.
- Programmer rapidement : plus vite une erreur est détectée, plus vite elle sera corrigée.
- Programmer sans régresser : lorsqu'un programme est correctement testé, le mieux est de le valider une bonne fois pour toute. Une amélioration pourrait « endommager » un programme qui avait déjà été testé et validé. Avec les tests unitaires, il est possible de garantir le bon fonctionnement du programme en question.
- Programmer en équipe : les tests unitaires sont essentiels pour un bon avancement dans une équipe de programmeurs. Plutôt que de valider le code de ses partenaires, il suffit de lancer les tests afin de vérifier le travail de chacun.
Comment les ecrires?
Ecrire un test revient à :
- Ecrire une classe qui étend junit.framework.TestCase par classe à tester (MaClasseTest.java pour tester MaClasse.java) ;
- Ecrire des méthodes testXXX qui utilisent des fonctions JUnit de type assertYYY (la méthode testAdd() pour add());
- Chaîner ces méthodes testXXX ;
- Exécuter ces chaînes de test.
Les méthodes assertYYY
L'intérêt majeur d'un test unitaire est d'échouer lorsque la fonctionnalité n'est pas confrome. Pour que la méthode testXXX échoue, il faut utiliser une des méthodes de la classe junit.framework.Assert.
Il existe plusieurs méthodes, les plus courantes sont :
- assertEquals : vérifier que deux objets sont égaux ;
- assertTrue : vérifier que l'expression est vrai ;
- assertFalse : vérifier que l'expression est fausse ;
- assertNull : vérifier que l'objet est null ;
- assertNotNull : vérifier que l'expression n'est pas null ;
- assertSame : vérifie que deux références sont les mêmes ;
- assertNotSame : vérifie que deux références ne sont pas les mêmes ;
- ...
La classe Assert en détails ici.
Exemple d'un test unitaire
Nous voulons tester une méthode simple d'addition. Notre classe s'appelle Calcul.java, la méthode à tester est addition(int a, int b) :
public class Calcul
{
public static int addition(int a, int b)
{
return (a+b);
}
}
A présent, nous écrivons notre classe test CalculTest.java ainsi que la méthode testAddition() :
import junit.framework.*;
public class CalculTest extends TestCase
{
public void testAddition()
{
assertTrue(5, Calcul.addition(2,3));
}
}
L'exécution des tests se fait de la même manière qu'avec JUnit, le résultat est donné de la même manière également.
La suite de tests
Les suites de tests permettent de regrouper plusieurs tests les uns après les autres. L'intérêt est d'automatiser l'ensemble des tests et de préciser un ordre d'exécution.
Pour créer une suite de tests, il faut créer une classe de type TestSuite et appeler la méthode addTest() pour chacune des classes de tests à ajouter. Cette méthode prend en paramètre une instance de la classe de tests. L'objet de type TestSuite ainsi créé doit être renvoyé par une méthode dont la signature doit obligatoirement être public static Test suite(). Celle ci sera appellée par introspection par un TestRunner.
import junit.framework.*;
public class ExecuterLesTests
{
public static Test suite()
{
TestSuite suite = new TestSuite("Les tests");
suite.addTestSuite(CalculTest.class);
suite.addTestSuite(UtilsTest.class);
return suite;
}
public static void main(String args[])
{
junit.textui.TestRunner.run(suite());
}
}
Documentation sur l'object TestSuite ici.
Documentation sur l'object TestRunner ici.