SVL - Cours-TD 1 Introduction au test du logiciel Premiers ... · Introduction au test du logiciel...
Transcript of SVL - Cours-TD 1 Introduction au test du logiciel Premiers ... · Introduction au test du logiciel...
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
SVL - Cours-TD 1Introduction au test du logiciel
Premiers pas avec JUnit
Mirabelle Nebut
Bureau 332 - M3mirabelle.nebut at lifl.fr
Master 1 info S2 - 2010.2011
Mirabelle Nebut Introduction au test 1
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnitAssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Mirabelle Nebut Introduction au test 2
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Definitions
[Myers] : Testing is the process of executing a program with theintent of finding errors
Procede de V&V (Verification et Validation) :
I le plus connu ;
I le moins couteux.
Mirabelle Nebut Introduction au test 3
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Finding errors
Pre-suppose du test :
tout code contient des erreurs
Le terme le plus usite est bug.
Mirabelle Nebut Introduction au test 4
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Bugs everywhere
I ds le calculateur de votre voiture ;
I ds le logiciel qui traite vos transactions bancaires (2006,2010) ;
I ds des logiciels critiques : Ariane 5, Mars Climate Orbiter, etc ;
I ds des logiciels tres critiques : Therac-25, missiles Patriot ;
I ds votre code.
Mirabelle Nebut Introduction au test 5
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Cout des bugs
Enorme !
I du point de vue de l’utilisateur : cout financier et humain ;
I du point de vue du developpeur : cout de la maintenance.
Il est possible de limiter ce cout en testant le code.
Mirabelle Nebut Introduction au test 6
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Qui teste ?
L’utilisateur final (toujours)
Les collegues charges du test (s’il y en a)
Le developpeur : il a le devoir de fournir un code le plus clair et lemieux teste possible.
Mirabelle Nebut Introduction au test 7
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Exemple a tester
Type enumere Level = { Low, Mid, High }
Classe LevelManagement :
I int getLowLevel()
I int getMidLevel()
I int getHighLevel()
I void setLevel(int low, int mid, int high)
I Level getLevel(int x)
Mirabelle Nebut Introduction au test 8
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Exemple a tester
Level getLevel(int x)
I leve une OutOfLevelException si x 6∈ [0, getHighLevel()]
I retourne Level.Low si x ∈ [0, getLowLevel()]
I retourne Level.Mid si x ∈ ]getLowLevel(), getMidLevel()]
I retourne Level.High six ∈ ]getMidLevel(), getHighLevel()]
Mirabelle Nebut Introduction au test 9
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Critere de test
D’abord on choisit un critere de test :
I tester une fonctionnalite donnee ;
I couvrir toutes les instructions d’un programme ;
I etc.
Par exemple, je decide de tester les methodes de la classeLevelManagement dans une approche :
I ”boıte noire” (on ne regarde pas le source) ;
I fonctionnelle : on verifie que les sorties sont correctes pour desentrees donnees.
Mirabelle Nebut Introduction au test 10
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Objectif de test
Ensuite on choisit une propriete ou caracteristique a tester enaccord avec le critere.
C’est l’objectif de test.
Ex : tester le comportement de la methode getLevel() quandx ∈]getLowLevel(), getMidLevel()].
Mirabelle Nebut Introduction au test 11
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Donnee de test
Ensuite on choisit une donnee de test.
Pour notre exemple, il faut choisir :
I une valeur pour chacun des trois seuils ;
I une valeur pour le parametre.
La donnee de test sera par exemple :
( lowLevel = 2,midLevel = 10,highLevel = 20,x = 7 )
Mirabelle Nebut Introduction au test 12
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Que doit repondre le test ?
Ensuite on infere de la specification le resultat attendu.
(Terminologie : parfois integre dans la donnee de test)
Souvent on se rend compte que la specification est des plusinformelles.
On en conclut que getLevel(7) doit retourner Level.Mid.
Mirabelle Nebut Introduction au test 13
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Test executable
On a ecrit un test abstrait.
= une description de test qu’on peut donner a quelqu’un.
Le plus souvent, ”test” = test executable.
= on � fait tourner � le systeme avec la donnee de test.
Dans notre exemple, si lm est un objet de type LevelManagement
tel que :
lowLevel = 2, midLevel = 10, highLevel = 20
alors on effectue lm.getLevel(7);
Mirabelle Nebut Introduction au test 14
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Oracle
On compare le resultat obtenu au resultat attendu : c’est l’oracle.
Dans notre exemple, l’oracle est :
lm.getLevel(7) = Level.Mid
L’oracle est toujours une assertion.
En objet le langage des assertions peut etre tres riche :
I expression booleenne
I levee d’une exception
I appel d’une methode sur tel objet avec tel parametre(interactions)
I etc
Mirabelle Nebut Introduction au test 15
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Verdict
On deduit de l’execution de l’oracle si le test a reussi ou echoue.
C’est le verdict.
Verdict classique pour une assertion ”booleenne” :
I elle vaut true : le test passe ;
I elle vaut false : le test echoue ;
I il y a une levee d’exception pas prevu : erreur, le test estinconclusif.
Mirabelle Nebut Introduction au test 16
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Associer verdict et oracle
On aimerait deduire automatiquement le verdict de l’execution dutest (via l’oracle).
En premiere approche, avec les moyens du bord :
...
try {
if (lm.getLevel(7) == Level.Mid)
S.O.P("test passe");
else
S.O.P("test echoue");
catch (Exception e) {
S.O.P("erreur, test inconclusif");
}
Mirabelle Nebut Introduction au test 17
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Fixture
Avant d’executer l’oracle, il faut amener l’objet dans uncontexte/etat favorable.
Cette preparation du contexte = fixture, installation, setUp ;
Dans notre exemple : creation de l’objet et positionnement de sonetat
LevelManagement lm = new LevelManagement();
lm.setLevel(2, 10, 20);
try { ... // oracle ...}
Mirabelle Nebut Introduction au test 18
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Cas de test
L’ensemble du test executable s’appelle un cas de test.
LevelManagement lm = new LevelManagement();
lm.setLevel(2, 10, 20);
try {
if (lm.getLevel(7) == Level.Mid)
S.O.P("test passe");
else
S.O.P("test echoue");
catch (Exception e) {
S.O.P("erreur, test inconclusif");
}
Mirabelle Nebut Introduction au test 19
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Suite de tests
On regroupe les cas de test par suite de tests :
I collection de cas de tests (abstraits ou executables) ;
I ou collection de suite de tests (abstraits ou executables).
Permet de :
I grouper des tests par concepts
I lancer des tests par paquets
Mirabelle Nebut Introduction au test 20
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
Exercice : cas de test
Ecrire un autre test pour getLevel() :
I en identifiant l’objectif de test (different du precedent) ;
I en identifiant la donnee de test ;
I en identifiant le resultat attendu ;
I en identifiant l’oracle ;
I en ecrivant la totalite du cas de test executable.
Reflechir a un/des cas de test pour setLevel(int, int, int).
Mirabelle Nebut Introduction au test 21
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
JUnit
Framework de test pour Java.
I Erich Gamma et Kent Beck
I TDD (test-driven developpment), Xtreme programming, agiledevelopment
I open source : www.junit.org
I integration dans Eclipse et Maven, utilisable avec Ant
Historiquement le premier framework Java.
Depuis il y a eu TestNG et tous les XUnit pour d’autres langages.
Mirabelle Nebut Introduction au test 22
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
JUnit 3.8, 4, 4.4, 4.5. . .
Grand saut entre JUnit3.8 et JUnit4 :
I nouvelle architecture
I nouvelles fonctionnalites
I nouveau style : JUnit4 = base sur annotations Java5
I plus simple d’utilisation
Acceleration des implantations de nouvelles fonctionnalites depuisla v4.
SVL : JUnit4
Mirabelle Nebut Introduction au test 23
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Ce que JUnit offre
JUnit is designed to efficiently capture developers’ intentions abouttheir code, and quickly check their code matches those intentions[junit.org]
I des assertions plus expressives pour exprimer les oracles ;
I la creation de suite de tests a grain fin ;
I le formatage du verdict, soit graphique, soit textuel ;
I la possibilite de lancer facilement les tests
I des fonctionnalites pour ecrire des tests toujours plus concis etlisibles
I = (presque) tout pour que tester soit plaisant et rapide.
Ce qu’il n’offre pas : des recettes pour trouver les bons tests !
Mirabelle Nebut Introduction au test 24
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Conventions pour SVL : organisation des sources
Les tests ne sont pas dans le source de l’applicatif !
Le repertoire de travail contient les repertoires (noms au choix) :
I classes (executables) ;
I src (sources) contenant les paquetages applicatifs ;
I test (tests) avec les memes paquetages.
Avantages :
I permet de livrer les tests ou non ;
I garde pour les tests la structure en paquetage de l’application ;
I plus facile de s’y retrouver.
Mirabelle Nebut Introduction au test 25
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Conventions pour SVL : utiliser Eclipse ?
Vous etes fan d’Emacs ? moi aussi ! Et pourtant, Eclipse aide autiliser JUnit !
Pour l’affichage graphique du verdict :
I JUnit3.8 proposait une interface graphique, mais JUnit 4 non ;
I or, c’est bon pour le moral de voir une belle barre verte. . .
I . . . plutot qu’un affichage console genre : ... OK (3 tests)
Pour l’aide dans l’ecriture des (import) :
I nombreux import a ecrire, fastidieux a retenir ;
I Eclipse les suggere.
Pour l’aide a la creation des suites de test.
Mirabelle Nebut Introduction au test 26
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnitAssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Mirabelle Nebut Introduction au test 27
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Les assertions de JUnit (base)
Servent a decrire l’oracle du cas de test.
I assertTrue(boolean condition), assertFalse(...)
I assertEquals(Object expected, Object actual)
I assert[Not]Same(Object expected, Object actual)
I assert[Not]Null(Object actual)
I assertEquals(double expected, double actual,
double delta)
I assertArrayEquals(<Type>[] expecteds, <Type>[]
actuals)
I fail()
Ne pas permettent pas d’exprimer des interactions entre objets.
Mirabelle Nebut Introduction au test 28
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Les assertions de JUnit : fonctionnement
Si l’assertion est violee :
I levee d’une erreur AssertionFailedError
I l’erreur fait echouer le test
Si l’assertion n’est pas violee : elle termine simplement.
Methodes definies statiquement dans la classe org.junit.Assert.
Mirabelle Nebut Introduction au test 29
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemples
import static org.junit.Assert.*;
assertSame(Level.Mid, lm.getLevel(7));
assertEquals(10, lm.getHighLevel());
assertTrue(lm.getLowLevel() <= lm.getHighLevel());
Mirabelle Nebut Introduction au test 30
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemple : cas des exceptions
try {
this.lmNominal.getLevel(-1);
fail(); // on ne doit pas passer ici
} catch (OutOfLevelException e) {
// OK
};
Il a plus simple, cf la suite.
Mirabelle Nebut Introduction au test 31
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Message d’erreur
assertEquals(lm1,lm2); // 2 objets differents
produira le message d’erreur suivant, qui n’aide pas :
java.lang.AssertionError:
expected:<levelStuff.LevelManagement@910040>
but was:<levelStuff.LevelManagement@1a786c3>
Le message d’erreur est construit a partir de lm1/2.toString()
⇒ implanter toString() pour les besoins du test
Mirabelle Nebut Introduction au test 32
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Message d’erreur
Si
assertEquals(lm1,lm2);
assertEquals(lm1,lm3);
produit :
java.lang.AssertionError:
expected:... but was:...
on ne sait pas quelle assertion a ete violee.
⇒ integrer des messages dans les assertions
Mirabelle Nebut Introduction au test 33
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Message d’erreur
Toutes les assertions peuvent commencer par un parametre String
Il sera affiche en cas d’erreur.
import static org.junit.Assert.*;
assertSame("level should be Mid", Level.Mid, lm.getLevel(7));
assertEquals("high level should be 10", 10, lm.getHighLevel());
fail("Exception OutOfLevelException should have been thrown");
Peut etre tres utile, ou alourdir inutilement le code.
Mirabelle Nebut Introduction au test 34
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnitAssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Mirabelle Nebut Introduction au test 35
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Classe de test
Ou classe contenant des cas des test (= suite de test).
Par convention, la classe de test qui teste la classelevelStuff.LevelManagement (repertoire src) a pour nomlevelStuff.TestLevelManagementBlaBlaBla (repertoiretest).
BlaBlaBla : description informative de la suite de test.
Mirabelle Nebut Introduction au test 36
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Classe de test
En JUnit4 : la classe de test est une simple classe Java.
Creation sous Eclipse :
I new JUnit Test Case
I choisir JUnit 4
I eventuellement choisir quelles methodes doivent etre testees.
package levelStuff;
public class TestLevelManagement {...}
Mirabelle Nebut Introduction au test 37
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Methode de test - JUnit4
Ou methode d’une classe de test, representant un cas de test.
I annotee par @Test ;
I import org.junit.Test ;
I publique, type de retour void ;
I pas de parametre, peut lever une exception.
Mirabelle Nebut Introduction au test 38
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Test JUnit4 : exemple
@Test
public void testGetLevelMidNominal()
throws OutOfLevelException {
LevelManagement lmNominal;
lmNominal = new LevelManagement();
lmNominal.setLevel(3, 10, 20);
assertSame(Level.Mid,lmNominal.getLevel(7));
// ici assertEquals est equivalent
}
Pour lancer ce test sous Eclipse : run as JUnit Test Case ourun as s’il y a des choses a configurer.
Mirabelle Nebut Introduction au test 39
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Le verdict de JUnit
I le test passe : OK
I le test echoue : failure
I exception inattendue : error
Graphiquement :
I le test passe : barre verte / croix verte Eclipse
I le test echoue : barre rouge / croix bleue Eclipse
I erreur : barre rouge / croix rouge Eclipse
Mirabelle Nebut Introduction au test 40
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Test JUnit4 : autre exemple
@Test
public void testGetLevelMidUpperLimit() throws OutOfLevelException {
LevelManagement lmNominal;
lmNominal = new LevelManagement();
lmNominal.setLevel(3, 10, 20);
assertSame(Level.Mid,lmNominal.getLevel(10));
}
JUnit permet de lancer les 2 tests d’un coup (on ne sait pas dansquel ordre).
Pour ignorer un test : @Ignore (a importer).
Sous Eclipse : on peut choisir finement quel test lancer.
Mirabelle Nebut Introduction au test 41
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Pour lancer les tests en textuel
Avec le Runner par defaut.
java org.junit.runner.JUnitCore
levelStuff.TestLevelManagement
JUnit version 4.1
..
Time: 0.021
OK (2 tests)
Si l’un des tests est @Ignore :
.I
Time: 0.021
OK (1 test)
Mirabelle Nebut Introduction au test 42
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Remarque
Apres l’ecriture des 2 tests, on realise que le code se repete !
Le fixture est logiquement commun a plusieurs tests :
I on reusine ;
I on utilise le fixture de JUnit.
Mirabelle Nebut Introduction au test 43
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Fixture JUnit : @Before
import org.junit.Before;
Preambule : methode annotee par @Before :
I par convention (heritee de JUnit3.8) appelee setUp ;
I publique, throws Exception ;
I appelee avant chaque appel d’une methode de test ;
I sert a factoriser la construction des objets.
Mirabelle Nebut Introduction au test 44
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
@Before - Exemple
public class TestLevelManagement {
private LevelManagement lmNominal;
@Before
public void setUp() throws Exception {
this.lmNominal = new LevelManagement();
this.lmNominal.setThreshold(3, 10, 20);
}
@Test
public void testGetLevelMidNominal()
throws OutOfLevelException {
assertSame(Level.Mid,lmNominal.getLevel(7));
}
... Mirabelle Nebut Introduction au test 45
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
@Before - Exemple
public class TestLevelManagement {
private LevelManagement lmNominal;
private LevelManagement lmLowIsMid;
@Before
public void setUp() throws Exception {
this.lmNominal = new LevelManagement();
this.lmNominal.setThreshold(3, 10, 20);
this.lmLowIsMid = new LevelManagement();
this.lmNominal.setThreshold(3, 3, 20);
}
@Test
public void testGetLevelMidLowIsMid()
throws OutOfLevelException {
assertSame(Level.Mid,lmLowIsMid.getLevel(3);
}
...Mirabelle Nebut Introduction au test 46
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Fixture : les autres methodes associees
Postambule : methode annotee par @After :
I par convention (heritee de JUnit3.8) appelee tearDown ;
I publique, throws Exception ;
I appelee apres chaque appel d’une methode de test.
Methodes avec annotations @BeforeClass et @AfterClass :
I publiques et statiques ;
I executees avant (resp. apres) l’appel de la premiere (resp.derniere) methode de test ;
I une seule methode pour chaque annotation ;
I pas en JUnit3.8.
Mirabelle Nebut Introduction au test 47
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Gestion des exceptions
@Test(expected=OutOfLevelException.class)
public void testGetLevelOutOfLowerBound()
throws OutOfLevelException {
this.lmNominal.getLevel(-1);
}
Raccourci pour :
try {
this.lmNominal.getLevel(-1);
fail();
} catch (OutOfLevelException e) {
};
Mirabelle Nebut Introduction au test 48
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Pour construire une suite de test JUnit
Difficile a memoriser. . .merci Eclipse !
I utilisation d’un autre runner que celui par defaut, leorg.junit.runners.Suite ;
I changer de runner par @RunWith(Suite.class) ;I pour indiquer comment former la suite de test : annotation
@SuiteClasses(Class[])
package ...;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.junit.runner.RunWith;
@RunWith(Suite.class)
@SuiteClasses({TestToto.class, TestTiti.class})
public class TestAll {} // vide
Mirabelle Nebut Introduction au test 49
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Remarque - nommage des methodes de test
Convention :
I le nom d’une methode qui teste la methode getLevel devraitcommencer par testGetLevel ;
I la suite du nom devrait indiquer l’objectif de test :testGetLevelOutOfLowerBound,testGetLevelNominalHigh,etc ;
I si l’objectif est trop complique a expliquer dans le nom dutest : s’inquieter, ou rajouter un commentaire.
Mirabelle Nebut Introduction au test 50
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Remarque - oracle(s)
Convention : un cas de test contient forcement un oracle.
Certaines ecoles imposent un seul oracle par cas de test.
Avantage : assertion clairement identifiee si le test echoue.
Inconvenients :
I oblige a dupliquer le fixture des tests
I parfois tres artificiel
⇒ tendre a limiter le nombre d’oracle, sans dogmatisme.
Mirabelle Nebut Introduction au test 51
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnitAssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Mirabelle Nebut Introduction au test 52
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Les inconvenients du assertEquals
assertEquals(String message,
Object expected, Object actual)
L’ordre ”expected, actual” n’est pas intuitif.
”j’aimerais que soient egaux ce que j’attends et ce que j’obtiens”
vs
”j’aimerais que ce que j’obtiens soit egal a ca”
Mirabelle Nebut Introduction au test 53
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Le assertThat
assertThat([actualValue], [matcher statement]);
Exemples :
assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(responseString,
either(containsString("color")).
or(containsString("colour")));
assertThat(myList, hasItem("3"));
Mirabelle Nebut Introduction au test 54
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Le assertThat
assertThat([actualValue], [matcher statement]);
Le matcher est de type org.hamcrest.Matcher
JUnit ne contient pas tout hamcrest :
I assertThat dans Assert ;
I classe org.junit.matchers.JUnitMatchers ;
I paquetage org.hamcrest.core.
Mirabelle Nebut Introduction au test 55
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Les Matcher fournis
JUnitMatchers :
I both, either, containsString, everyItem, hasItem
org.hamcrest.core :
I Is : is(Class), is(Matcher<t>), is(T)
I IsEqual : equalTo(T) ;
I IsNot : not(Matcher<t>), not(T) ;
I et d’autres
Mirabelle Nebut Introduction au test 56
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Avantages
Permet d’ecrire ses propres Matcher
Permet des messages d’erreurs bcp plus parlants.
assertTrue(responseString.contains("color")
|| responseString.contains("colour"));
// ==> failure message:
// java.lang.AssertionError:
assertThat(responseString,
anyOf(containsString("color"), containsString("colour")));
// ==> failure message:
// java.lang.AssertionError:
// Expected: (a string containing "color" or
// a string containing "colour")
// got: "Please choose a font"
Mirabelle Nebut Introduction au test 57
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnitAssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Mirabelle Nebut Introduction au test 58
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Tests parametres (JUnit 4)
Pour factoriser les donnees de test si combinatoire :
I ecriture separee des tests (oracle) et des donnees de test
I les donnees incluent le resultat attendu
I le runner fait le produit en croix des donnees de test et desmethodes de test.
Mirabelle Nebut Introduction au test 59
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemple - test parametre
Test de la methode int sum (int x, int y) deparamSum::Sum
package paramSum;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.*;
import java.util.*;
@RunWith(Parameterized.class)
public class TestParamSum { ... }
Mirabelle Nebut Introduction au test 60
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemple - test parametre
private int x;
private int y;
private int res;
public TestParamSum(int x, int y, int res) {
this.x = x;
this.y = y;
this.res = res;
}
Mirabelle Nebut Introduction au test 61
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemple - test parametre
@Parameters
public static Collection testData() {
return Arrays.asList(new Object[][] {
{ 0, 0, 0 },
{ 1, 1, 2 },
{ 2, 1, 3 },
{10, 9, 19}});
}
@Test
public void testSum() {
assertEquals(res,new Sum().sum(x,y));
}
Mirabelle Nebut Introduction au test 62
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Exemple - test parametre
> java org.junit.runner.JUnitCore paramSum.TestParamSum
JUnit version 4.1
....
Time: 0.397
OK (4 tests)
Mirabelle Nebut Introduction au test 63
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Test parametre - resume
I runner org.junit.runners.Parameterized
I donnees fournies par une methode publique statique quiretourne une collection et est annotee par @Parameters ;
I constructeur public pour la classe de test qui prend enparametre les donnees et le resultat attendu ;
Mirabelle Nebut Introduction au test 64
Qu’est-ce que le testQu’est-ce qu’un test : terminologie
Tester avec JUnit
AssertionsClasses et methodes de testAssertions version assertThat (JUnit4.4)Autres fonctionnalites
Assumptions (JUnit4.4)
Permet d’exprimer le contexte dans lequel le test est supposepasser, ou d’exhiber un bug.
Si la supposition est fausse le test passe.
import static org.junit.Assume.*
@Test public void filenameIncludesUsername() {
assumeThat(File.separatorChar, is(’/’));
assertThat(new User("optimus").configFileName(),
is("configfiles/optimus.cfg"));
}
@Test public void correctBehaviorWhenFilenameIsNull() {
assumeTrue(bugFixed("13356"));
// bugFixed is not included in JUnit
assertThat(parse(null), is(new NullDocument()));
}
Mirabelle Nebut Introduction au test 65