IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Des dev et des tests

Thierry

Date de publication : 22 novembre 2010

Par Thierry Leriche-Dessirier (www.thierryler.com)
 

Tous les acteurs du développement s'accordent sur l'importance de tester les applications. On parle de qualité totale, de tests unitaires, de tests de charge, de couverture de code, de test de non régression, etc. Pourtant les tests sont, d'expérience, parmi les premiers à faire les frais des budgets limités. On les accuse de couter cher, d'être longs à écrire et/ou à maintenir, pour finalement les mettre au rancard. C'est une grave erreur car des tests bien pensés augmentent considérablement la productivité de l'ensemble des étapes des projets. L'éventail des types et topologies de tests est relativement vaste et permet aux équipes de trouver les solutions adaptés à la plupart de leurs besoins. Cet article présente une sélection d'outils importants, dans le cadre des stratégies de test, dans laquelle chaque projet gagne à puiser son inspiration.

       Version PDF (Miroir)   Version hors-ligne (Miroir)
Viadeo Twitter Facebook Share on Google+        



I. Intro
II. Méthodologie
II-A. TDD
II-B. Coût des tests
III. Tests unitaires avec JUnit
IV. Le printemps (Spring) dans les tests
V. Une base de données en mémoire avec DBUnit
VI. Des bouchons avec Mockito
VII. Des simulacres avec EasyMock
VIII. Tests d'intégration
IX. Non régression (NR) avec Selenium
IX-A. Selenium IDE
IX-B. Coté Java, local/remote
IX-C. Pour la recette
X. Des rapports avec Maven et Sunfire
XI. La couverture de test avec Cobertura
XII. Vie, évolution et mort des tests
XIII. Conclusions
XIV. Annexes


I. Intro

TODO


II. Méthodologie

TODO


II-A. TDD

TODO


II-B. Coût des tests

TODO


III. Tests unitaires avec JUnit

JUnit est un framework dédié aux tests unitaires. C'est sans aucun doute le framework de test le plus connu et le plus utilisé, au point qu'on assimile souvent (à tord) JUnit aux tests de manière générale. Il est impossible de faire l'impasse sur JUnit tellement le framework est au cœur des stratégies de développement mais également parce qu'il est mis en œuvre par la plupart des mécanismes de test.

L'objectif des tests unitaires est de valider le bon fonctionnement des fonctionnalités des programmes de manière autonomes. Une classe de test spécifie le jeu de test et contrôle que les traitements sont correcte. Un test unitaire s'auto suffit et ne doit surtout pas dépendre d'un élément externe comme un web service ou la base de données.

Dans les projets modernes, il suffit d'indiquer une dépendance à JUnit dans le fichier pom.xml en précisant un scope de test.
Dépendance à JUnit dans le pom

<dependency>  
	<groupId>junit</groupId>  
	<artifactId>junit</artifactId>  
	<version>4.8</version>  
	<scope>test</scope>  
</dependency> 
Comme pour n'importe quelle dépendance, il suffit de demander à Maven de générer la configuration pour utiliser JUnit dans Eclipse.
Maven et Eclipse

mvn eclipse:eclipse

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building dev-et-tests
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse {execution: default-cli}]
[INFO] Using Eclipse Workspace: null
[INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER
[INFO] File D:\javadev\article\developpez.com\dev-et-tests\.project already exists.
       Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
[INFO] Wrote Eclipse project for "dev-et-tests" to D:\javadev\article\developpez.com\dev-et-tests.
[INFO]
       Sources for some artifacts are not available.
       Please run the same goal with the -DdownloadSources=true parameter in order to check remote repositories for sources.
       List of artifacts without a source archive:
         o junit:junit:4.8.1

       Javadoc for some artifacts is not available.
       Please run the same goal with the -DdownloadJavadocs=true parameter in order to check remote repositories for javadoc.
       List of artifacts without a javadoc archive:
         o junit:junit:4.8.1

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Tue Dec 28 20:17:12 CET 2010
[INFO] Final Memory: 8M/21M
[INFO] ------------------------------------------------------------------------
info Dans un projet Maven, les classes Java sont placées dans le dossier "src/main/java" et les classes de test dans le dossier "src/test/java".
Pour réaliser des tests, encore faut-il avoir quelque chose à tester. Une bonne pratique, comme dans le cadre d'une stratégie DDT (Développement Dirigé par les Tests), consiste à écrire en premier les interfaces des programmes, puis les tests utilisant ces interfaces, en précisant les données d'entrée et les résultats attendus, puis finalement de programmer les implémentations à proprement dit.

Un simple programme de calculette fera un très bon exemple. En voici l'interface initiale.
Interface d'une calculette

public interface Calculette {
	int add(int a, int b);
	int multiply(int a, int b);
}
Les classes de test sont, par convention, postfixées par "Test" ou "TestCase" et exposent des méthodes "public void" annotées par "@Test". En général, on écrit au moins une méthode de test pour chaque méthode de l'interface à valider.
Classe de test

import junit.framework.Assert;

import org.junit.Test;

public class CalculetteTestCase {
	private Calculette calculette;

	@Test
	public void testAdd() {
		final int a = 2;
		final int b = 3;

		int result = calculette.add(a, b);

		Assert.assertEquals(5, result);
	}

	@Test
	public void testMultiply() {
		final int a = 2;
		final int b = 3;

		int result = calculette.multiply(a, b);

		Assert.assertEquals(6, result);
	}
}
La méthode "Assert.assertEquals()" permet de comparer une valeur attendue avec le résultat (réel) d'une méthode.

A ce stade, il est temps d'écrire l'implémentation de la calculette.
Implémentation de la calculette

public class DefaultCalculette implements Calculette {

	@Override
	public int add(int a, int b) {
		return a + b;
	}

	@Override
	public int multiply(int a, int b) {
		return a * b;
	}
}	
Cette implémentation peut ensuite être utilisée par les tests. Pour cela il faut compléter CalculetteTestCase avec la méthode setUp(), nommée ainsi par convention à cause des anciennes versions de JUnit, et annotée par @Before. Cette méthode est appellée automatiquement avant chaque test, étant dit que chaque méthode annotée avec @Test définit un test. Dans l'exemple, la méthode setUp() sera donc appellée 2 fois.
Méthode setUp() annotée @Before

public class CalculetteTestCase {

	private Calculette calculette;

	@Before
	public void setUp() {
		calculette = new DefaultCalculette();
	}

IV. Le printemps (Spring) dans les tests

TODO


V. Une base de données en mémoire avec DBUnit

TODO


VI. Des bouchons avec Mockito

TODO


VII. Des simulacres avec EasyMock

TODO


VIII. Tests d'intégration

TODO


IX. Non régression (NR) avec Selenium

TODO


IX-A. Selenium IDE

TODO


IX-B. Coté Java, local/remote

TODO


IX-C. Pour la recette

TODO


X. Des rapports avec Maven et Sunfire

TODO


XI. La couverture de test avec Cobertura

TODO


XII. Vie, évolution et mort des tests

TODO


XIII. Conclusions

TODO


XIV. Annexes

TODO



               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Thierry Leriche-Dessirier. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.