Vous êtes sur la page 1sur 47

FORMATION JAVA FRAMWORK

JUNIT
Plan
Principaux types de test
Principe du test unitaire
Automatisation des tests unitaires
Dveloppement conduit par les Test
Diffrents types de tests (1)
Les tests unitaires
Les tests unitaires consistent tester individuellement les composants de lapplication. On
pourra ainsi valider la qualit du code et les performances d'un module.

Les tests d'intgration


Ces tests sont excutes pour valider l'intgration des diffrents modules entre eux et dans
leur environnement exploitation dfinitif.
Ils permettront de mettre en vidence des problmes d'interfaces entre diffrents
programmes.
Les tests fonctionnels
Ces tests ont pour but de vrifier la conformit de l'application dveloppe avec le cahier des
charges initial. Ils sont donc bass sur les spcifications fonctionnelles et techniques.

Les tests de non-rgression


Les tests de non-rgression permettent de vrifier que des modifications n'ont pas altres le
fonctionnent de l'application.
L'utilisation d'outils de tests, dans ce dommaine, permet de facilit la mise en place de ce type
de tests.
Diffrents types de tests (2)
Les tests IHM
Les tests IHM ont pour but de vrifier que la charte graphique a t respecte tout au long du dveloppement.

Cela consiste contrler :


la prsentation visuelle : les menus, les paramtres d'affichages, les proprits des fentres, les barres d'icnes, la
rsolution des crans, les effets de bord,
la navigation : les moyens de navigations, les raccourcis, le rsultat d'un dplacement dans un cran,

Les tests de configuration


Une application doit pouvoir s'adapter au renouvellement de plus en plus frquent des ordinateurs. Il s'avre donc
indispensable d'tudier l'impact des environnements d'exploitation sur son fonctionnement.

Voici quelques sources de problmes qui peuvent surgir lorsque l'on migre une application vers un environnement
diffrent :
l'application dveloppe en 16 bits migre sur un environnement 32 bits,
les DLL sont incompatibles,
les formats de fichiers sont diffrents,
les drivers de priphriques changent,
les interfaces ne sont pas gres de la mme manire...

Ainsi, pour faire des tests efficaces dans ce contexte, il est ncessaire de fixer certains paramtres comme par
exemple :
la mme rsolution graphique,
le mme nombre de couleurs l'cran,
une imprimante identique,
les mmes paramtres pour le rseau...
Diffrents types de tests (3)
Les tests de performance
Le but principal des tests de performance est de valider la capacit qu'ont les serveurs et les rseaux
supporter des charges d'accs importantes.

On doit notamment vrifier que les temps de rponse restent raisonnable lorsqu'un nombre
important d'utilisateurs sont simultanment connects la base de donnes de l'application.
Pour cela, il faut d'abord relever les temps de rponse en utilisation normale, puis les comparer aux
rsultats obtenus dans des conditions extrmes d' utilisation.

Une solution est de simuler un nombre important d'utilisateur en excutant l'application partir
d'un mme poste et en analysant le trafic gnr.

Le deuxime objectif de ces tests est de valider le comportement de l'application, toujours dans des
conditions extrmes. Ces tests doivent permettrent de dfinir un environnement matriel minimum
pour que l'application fonctionnement correctement.

Les tests d'installation


Une fois l'application valide, il est ncessaire de contrler les aspects lis la documentation et
l'installation.

Les procdures d'installation doivent tre testes intgralement car elles garantissent la fiabilit de
l'application dans la phase de dmarrage.
Bien sr, il faudra aussi vrifier que les supports d'installation ne contiennent pas de virus.
Principe du test unitaire
Un test est unitaire lorsque :
Il ne communique pas avec la base de donnes
Il ne communique pas avec dautres ressources sur le
rseau
Il ne manipule pas un ou plusieurs fichiers
Il peut sexcuter en mme temps que les autres tests
unitaires
On ne doit pas faire quelque choses de spcial, comme
diter un fichier de configuration, pour lexcuter

Et gnralement un test unitaire est petit et rapide, il vrifie le


traitement dune mthode de classe et des interactions
avec dautres mthodes de classe. Ainsi tout ce qui nest
pas un test unitaire constitue alors un test dintgration.
Principe du test unitaire
Maintenant, il se peut que lon ait dvelopper
une classe dont la responsabilit est daccder
la base de donnes. On dispose alors de plusieurs
choix pour tester cette classe :

Ecrire un test unitaire en utilisant des objets


bouchons (Mock Objects) sur la couche de connexion
la base de donne
Ecrire un test unitaire en bouchonnant la base de
donnes relle par une base de donnes mmoire
(par exemple HSQLDB)
Ecrire un test dintgration avec le code et la base de
donnes
Junit
JUnit fait partie de ces outils qui aident le
programmeur dans ce sens. Il est tout d'abord
bon de savoir que JUnit n'est pas une usine gaze
qui permet d'automatiser les tests de
fonctionnalits macroscopiques (celles fixes par
le client). JUnit est quelque chose de trs simple,
destin aux personnes qui programment. JUnit
est tellement petit et tellement simple que la
seule comparaison possible en terme de rapport
complexit d'utilisation / utilit est le bon vieux
"println" ou les "assertions".
Pouquoi Junit
Pourquoi JUnit peut-t-il ce point rvolutionner l'efficacit avec
laquelle vous programmez ?
Un programmeur qui vient de programmer un petit morceau de
programme buggu va s'aider d'un debuggeur ou de la sortie texte
sur la console pour savoir ce que fait son petit morceau de code. Un
programmeur qui utilise JUnit va avant d'crire le petit morceau de
code bugg d'abord se demander ce que le petit morceau de
programme doit faire, puis il va crire un petit bout de code capable
de vrifier si la tache a bien t ralise, l'aide du framework
JUnit (le test unitaire). Enfin il va raliser le petit morceau de code
qu'il devait faire, et il va constater que son code est bugg parce
que le test unitaire ne passe pas. Le test unitaireconstate en effet
que la tache n'est pas complte. Le programmeur qui utilise JUnit
va alors dbugger son code jusqu' ce que la tache soit
correctement ralise (Rq: Il va ventuellement utiliser un
debugger ou des affichage sur la sortie texte pour y parvenir).
Pourquoi faire tout a ? (pourquoi
travailler plus, je n'ai pas le temps !)
Parce que pour une raison ou pour une autre, vous devez programmer efficacement. Vous ne
pouvez pas vous permettre de sortir des sentiers battus en programmant "hors sujet" ou en
oubliant une fonctionnalit. Votre seul objectif en programment est alors de passer les tests
unitaires.
Toujours dans un soucis d'efficacit, vous ne pouvez pas passer non plus votre temps chercher un
bug (ou vous n'aimez pas faire a...). Que se serait-il pass si le programmeur n'avait pas constat le
bug ? Si vous dveloppez une test unitaire, vous vous ajoutez une marge de scurit. Vous laissez
moins de bugs derrire vous.
Parce que vous voulez savoir si vous n'tes pas en train de faire rgresser votre code. JUnit vous
dira tout de suite si vous avez perdu une fonctionnalit en cours de route, par exemple aprs avoir
supprim 200 lignes de code en pensant bien faire. Ant peut faire appel JUnit : vous saurez
chaque compilation s'il y a eu rgression. Le refactoring devient moins difficile et alatoire : vous
gagnerez l encore en efficacit. A noter que JUnit est conu la base pour viter ce genre de
problme...
Parce que vous travaillez plusieurs sur un projet. Vous avez (ou en tout cas vous aurez) une plus
grande confiance dans un bout de code fourni avec son test unitaire que dans un bout de code
fourni sans. Si voir la barre verte (signe d'un test pass avec succs) n'est pas suffisant pour gagner
votre confiance, vous avez alors une seconde possibilit de vrifier le bon fonctionnement, qui est
plus rapide que la lecture du code source : la lecture du test. Si le test vous inspire confiance et qu'il
passe, alors pourquoi perdre du temps en lisant (pour ne pas dire dcrypter !) le code source ? Vous
pouvez enfin faire confiance au code des autres, et vous concentrer sur la rsolution de vos bugs
vous ! L encore, vous pouvez gagner en terme d'efficacit.
Junit : Basiques
Classes de tests standardises
Classe qui tend junit.framework.TestCase
Ne contient pas de main
Contient des mthodes testXXXXXX()
Charges automatiquement
Les mthodes doivent contenir des assertions
assertTrue(bool condition)
assertEquals(int a, int b)
fail()
JUnit appliqu un projet
Convention de nommage
Convention pour structurer le projet
Convention pour raliser les tests
Travail en binome autour d'une spcification
Interface puis tests puis implmentation
Test si possible non triviaux
Test des mthodes publiques
Excuter les tests en mme temps que la
compilation
La dfinition des cas de tests
Chaque classe de tests doit avoir obligatoirement au moins une
mthode de test sinon une erreur est remonte par JUnit.
La dcouverte des mthodes de tests par Junit repose sur
lintrospection :
JUnit recherche les mthodes qui dbutent par test, nont aucun
paramtre et ne retourne aucune valeur.
Ces mthodes peuvent lever des exceptions qui sont
automatiquement captures par JUnit qui remonte alors une erreur
et donc un chec du cas de tests.
Ds quun test choue, lexcution de la mthode correspondante
est interrompue et JUnit passe mthode suivante.
Avec JUnit, la plus petite unit de tests est lassertion dont le
rsultat de lexpression boolenne indique un succs ou une erreur.
La dfinition des cas de tests
Les cas de tests utilisent des affirmations (assertion en anglais) sous la forme de
mthodes nommes assertXXX().
Il existe de nombreuses mthodes de ce type qui sont hrites de la classe
junit.framework.Assert :
La dfinition des cas de tests
Bien quil serait possible de nutiliser que la mthode assertTrue(), les autres
mthodes assertXXX() facilite lexpression des conditions de tests.
Chacune de ces mthodes possde une version surcharge qui accepte un
paramtre supplmentaire sous la forme dune chane de caractres indiquant un
message qui sera affich en cas dchec du cas de test.
Le message doit dcrire le cas de test valu "true".
Lutilisation de cette version surcharge est recommande car elle facilite
lexploitation des rsultats des cas de tests.
Exemple :
La dfinition des cas de tests
Lordre des paramtres contenant la valeur attendue et la
valeur obtenue est important pour obtenir un message
derreur fiable en cas dchec du cas de test.
Quelque soit la surcharge utilise lordre des deux valeurs
tester est toujours la mme : cest toujours la valeur
attendue qui prcde la valeur courante.
La mthode fail() permet de forcer le cas de test chouer.
Une version surcharge permet de prciser un message qui
doit tre afficher.
Il est aussi souvent utile lors de la dfinition des cas de tests
de devoir tester si une exception est leve lors de
lexcution.
Lhritage dune classe de base
Il est possible de dfinir une classe de base qui servira
de classe mre dautres classes de tests notamment
en leur fournissant des fonctionnalits communes.
JUnit nimpose pas quune classe de tests drive
directement de la classe TestCase.
Ceci est particulirement pratique lorsque lon souhaite
que certaines initialisations ou certains traitements soit
systmatiquement excuts (exemple chargement dun
fichier de configuration, ...).
Il est par exemple possible de faire des initialisations
dans le constructeur de la classe mre et invoquer ce
constructeur dans les constructeurs des classe filles.
JUnit: Mon premier test automatique
Dmarche
Nous allons voir comment crire notre premier test unitaire pas pas. Pour ce
faire, nous utiliserons le projet de la calculatrice comme exemple.
Tout dabord, nous crerons le projet de calculatrice.
Puis nous crirons la classe daddition.
Ensuite, il faudra crer le rpertoire des tests dans lequel seront classs tous
les tests. Chaque quipe peut dcider de la faon dont elle souhaite organiser
son rpertoire de code source et en particulier le code de test. Il existe
nanmoins une faon classique de procder qui consiste crer un dossier de
tests symtrique au rpertoire des sources pour y classer les tests selon la
mme organisation de paquet. Cette faon de procder a lavantage disoler
les classes de tests des classes de source tout en permettant aux tests
daccder la porte de dfinition du paquet. Ainsi, lors de la gnration de
code, il est simple disoler les tests du code tout en gardant les classes de tests
proches du code source dans une vue par paquet.
Enfin, nous pourrons crire la classe de tests voulue.
GUIDE PAS PAS (ECLIPSE)
Cliquez sur File New Java Project.
Nommez votre projet calculatrice en laissant les options par dfaut puis cliquez sur
OK.
Ajoutez un package math dans le rpertoire src.
Ajoutez la classe Addition dans le rpertoire src.

Ajoutez un nouveau dossier de sources nomm tests au mme niveau


darborescence que src.
Dans lexplorateur de paquets, faites un clic droit sur la classe Addition.
Dans le menu contextuel, cliquez sur New JUnit Test Case.
GUIDE PAS PAS (ECLIPSE)
Un panneau saffiche alors :
GUIDE PAS PAS (ECLIPSE)
Dans ce panneau :
Slectionnez le bouton radio New JUnit 4 test.
Changez le dossier Source folder pour tests.
Nommez la classe AdditionTest.
Cochez les cases setUp() et tearDown().
Dans le champ Class under test, saisissez math.Addition.
Enfin cliquez sur Finish.
Eclipse va remarquer que la bibliothque de JUnit est absente
du projet et vous propose dajouter automatiquement cette
dernire au projet.
Dans le panneau qui apparat, cliquez sur OK.
GUIDE PAS PAS (ECLIPSE)
Eclipse va maintenant crer automatiquement le squelette de
la classe de test :
GUIDE PAS PAS (ECLIPSE)
Il ne reste plus alors qu remplir cette dernire.
GUIDE PAS PAS (ECLIPSE)
Dans lexplorateur de paquets, faites un clic droit sur la classe
AdditionTest.
Dans le menu contextuel, cliquez sur Run As JUnit test.
Enfin, le premier rapport de tests saffiche !
GUIDE PAS PAS (ECLIPSE)
GUIDE PAS PAS (ECLIPSE)
La barre de progression est rouge, indiquant
quau moins un test est en chec. Le rapport
derreur permet de visualiser les tests en
chec et dafficher la cause et lorigine du
problme. Dans ce cas, une erreur sest glisse
sur le symbole de laddition!
Lexcution des tests (1/2)
JUnit propose trois applications diffrentes nommes TestRunner
pour excuter les tests en mode ligne de commande ou application
graphique :
une application console : junit.textui.TestRunner qui est trs rapide et
adapte une intgration dans un processus de gnrations
automatiques.
une application graphique avec une interface Swing :
junit.swingui.TestRunner.
une application graphique avec une interface AWT :
junit.awtui.TestRunner.
Quelque soit lapplication utilise, les entits suivantes doivent tre
incluses dans le classpath :
le fichier junit.jar.
les classes tester et les classes des cas de tests.
les classes et bibliothques dont toutes ces classes dpendent.
Lexcution des tests (2/2)
Suite lexcution dun cas de test, celui ci peut avoir un
des trois tats suivants :
chou : une exception de type AssertionFailedError est leve.
en erreur : une exception non mise par le framework et non
capture a t leve dans les traitements.
pass avec succs.
Lchec dun seul cas de test entrane lchec du test
complet.
Lchec dun cas de test peut avoir plusieurs origines :
le cas de test contient un ou plusieurs bugs.
le code tester contient un ou plusieurs bugs.
le cas de test est mal dfini.
une combinaison des cas prcdents simultanment.
Les suites de tests (1/2)
Les suites de tests permettent de regrouper plusieurs tests
dans une mme classe.
Ceci permet lautomatisation de lensemble des tests inclus
dans la suite et de prciser leur ordre dexcution.
Pour crer une suite, il suffit de crer une classe de type
TestSuite et dappeler la mthode addTest() pour chaque
classe de tests ajouter.
Celle ci attend en paramtre une instance de la classe de
tests qui sera ajoute la suite.
Lobjet de type TestSuite ainsi cr doit tre renvoy par
une mthode dont la signature doit obligatoirement tre
public static Test suite().
Les suites de tests (2/2)
Celle ci sera appele par introspection par le TestRunner.
Il peut tre pratique de dfinir une mthode main() dans
laclasse qui encapsule la suite de tests pour pouvoir
excuter le TestRunner de la console en excutant
directement la mthode statique Run().
Ceci vite de lancer JUnit sur la ligne de commandes.
Deux versions surcharges des constructeurs permettent
de donner un nom la suite de tests.
Un constructeur de la classe TestSuite permet de crer
automatiquement par introspection une suite de tests
contenant tous les tests de la classe fournie en paramtre.
La mthode addTestSuite() permet dajouter une suite
une autre suite.
Guide pas pas
Dans cette partie, on crera une suite de tests ave
excution sous la console de la jvm
Etapes :
Cration dun dossier JUNIT_WORKSPACE
Cration de la classe MessageUtil.java
Cration des Classes Test Case
Cration de la classe Test Suite
Cration de la classe Test Runner
Compilation de tous les lments avec javac
Excution de TestRunner sous la console
Guide pas pas
Cration de la classe MessageUtil.java
Guide pas pas
Cration du testcase 1

Cration du testcase 2:
Guide pas pas
Cration du testcase 1

Cration du testcase 2:
Guide pas pas
Compilation

Excution

Sortie console :
Intgration de JUnit dans Maven
Organisation
Guide pas pas
Taper la commande :
mvn archetype:create -DgroupId=exemple -DartifactId=calculatrice -
Dversion=1.0
Maven va crer un dossier calculatrice qui contient un fichier pom.xml.
ditez ce fichier.

Changez simplement le numro de version pour 4.7.


Guide pas pas
Ajoutez galement la section suivante pour indiquer
que nous souhaitons compiler en Java 1.x
Guide pas pas
Crez le rpertoire src/main/java/math.
Sauvegardez-y le fichier Addition.java.
Guide pas pas
Crez le rpertoire
src/test/java/math.
Sauvegardez-y le fichier
AdditionTest.java.
Guide pas pas
Enfin, lancez la commande suivante : mvn test
Test driven development
Le test-driven development (TDD) ou en franais dveloppement
pilot par les tests est une technique de dveloppement de
logiciel qui prconise d'crire les tests unitaires avant d'crire
le code source d'un logiciel.
L'objectif du TDD est de produire du "code propre qui fonctionne".
Pour cela, deux principes sont mis en oeuvre :
un dveloppeur crit du code nouveau seulement lorsqu'un test
automatis a chou
toute duplication de code (ou plus gnralement d'information, ou de
connaissances) doit tre limine. L'acronyme anglais DRY (Do not
Repeat Yourself) peut tre utilis comme moyen mnmotechnique
pour cette phase trs importante.
Ces deux principes doivent tre strictement respects, mme s'ils
paraissent difficiles ou bizarres dans un premier temps. Bien
comprendre le TDD suppose en effet de respecter strictement la
discipline impose par le cycle dcrit ci-dessous.
Test driven development
Bien que simples, ils ont diverses implications :
nous allons concevoir notre code de manire
incrmentale, en ayant toujours du code en tat de
marche, de telle sorte que ce code nous fournisse de
l'information pour prendre de nombreuses petites
dcisions au cours de notre dveloppement.
nous devons crire nos propres tests, parce que nous ne
pouvons pas attendre de nombreuses fois par jour qu'une
autre personne le fasse
notre environnement de dveloppement doit fournir une
rponse ultra rapide en cas de petits changements
notre code doit tre compos d'lments trs cohrents et
trs peu coupls, afin de rendre le test facile.
Test driven development
Le travail se fait en trois phases. Les deux premires sont nommes
d'aprs la couleur de la barre de progrs dans les outils comme Nunit :
ROUGE: crire un petit test qui choue, voire mme ne compile pas dans un
1er temps
VERT : faire passer ce test le plus rapidement possible, en s'autorisant si
besoin les "pires" solutions : S'il existe une solution propre, simple et
immdiate, ralisez-laSi une telle solution prend plus d'une minute, notez la et
revenez au problme principal : avoir une barre de progrs verte en quelques
secondes
REMANIEMENT (refactoring en anglais) : liminer absolument toute
duplication apparue durant les tapes 1 et 2.
Pour raliser l'tape 2 ci-dessus, il y a trois stratgies :
Simulation : retourner une constante, puis remplacer progressivement ces
constantes avec des variables afin d'obtenir le code rel
Implmentation vidente : taper directement la bonne solution
Triangulation : avoir deux exemples du rsultat recherch, et gnraliser.
Cycle de travail
Le cycle de travail en TDD est donc le suivant
:
ajouter rapidement un nouveau test
Excuter tous les tests, et constater l'chec du
nouveau : ROUGE
Faire un petit changement
Excuter tous les tests, et constater qu'ils passent
: VERT
Remanier le code pour liminer toute duplication :
REMANIEMENT
Test driven development

Vous aimerez peut-être aussi