8 par page

Transcription

8 par page
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
SVL - Cours-TD 1
Introduction au test du logiciel
Premiers pas avec JUnit
Mirabelle Nebut
Bureau 332 - M3
mirabelle.nebut at lifl.fr
Master 1 info S2 - 2010.2011
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Introduction au test 1
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 2
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Définitions
Finding errors
[Myers] : Testing is the process of executing a program with the
intent of finding errors
Pré-supposé du test :
tout code contient des erreurs
Procédé de V&V (Vérification et Validation) :
I
le plus connu ;
I
le moins coûteux.
Le terme le plus usité est bug.
Mirabelle Nebut
Introduction au test 3
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 4
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Bugs everywhere
Coût des bugs
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 très critiques : Therac-25, missiles Patriot ;
I
ds votre code.
Mirabelle Nebut
Énorme !
I
du point de vue de l’utilisateur : coût financier et humain ;
I
du point de vue du développeur : coût de la maintenance.
Il est possible de limiter ce coût en testant le code.
Introduction au test 5
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 6
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qui teste ?
Exemple à tester
Type énuméré Level = { Low, Mid, High }
Classe LevelManagement :
L’utilisateur final (toujours)
Les collègues chargés du test (s’il y en a)
Le développeur : il a le devoir de fournir un code le plus clair et le
mieux testé possible.
Mirabelle Nebut
Introduction au test 7
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 test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Exemple à tester
Critère de test
D’abord on choisit un critère de test :
Level getLevel(int x)
I
I
I
I
lève une OutOfLevelException si x 6∈ [0, getHighLevel()]
retourne Level.Low si x ∈ [0, getLowLevel()]
retourne Level.Mid si x ∈ ]getLowLevel(), getMidLevel()]
retourne Level.High si
x ∈ ]getMidLevel(), getHighLevel()]
Mirabelle Nebut
I
tester une fonctionnalité donnée ;
I
couvrir toutes les instructions d’un programme ;
I
etc.
Par exemple, je décide de tester les méthodes de la classe
LevelManagement dans une approche :
I
”boı̂te noire” (on ne regarde pas le source) ;
I
fonctionnelle : on vérifie que les sorties sont correctes pour des
entrées données.
Introduction au test 9
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 10
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Objectif de test
Donnée de test
Ensuite on choisit une donnée de test.
Pour notre exemple, il faut choisir :
Ensuite on choisit une propriété ou caractéristique à tester en
accord avec le critère.
C’est l’objectif de test.
I
une valeur pour chacun des trois seuils ;
I
une valeur pour le paramètre.
La donnée de test sera par exemple :
Ex : tester le comportement de la méthode getLevel() quand
x ∈]getLowLevel(), getMidLevel()].
Mirabelle Nebut
( lowLevel = 2,
midLevel = 10,
highLevel = 20,
x=7
)
Introduction au test 11
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 12
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Que doit répondre le test ?
Test exécutable
On a écrit un test abstrait.
Ensuite on infère de la spécification le résultat attendu.
(Terminologie : parfois intégré dans la donnée de test)
Souvent on se rend compte que la spécification est des plus
informelles.
On en conclut que getLevel(7) doit retourner Level.Mid.
= une description de test qu’on peut donner à quelqu’un.
Le plus souvent, ”test” = test exécutable.
= on
fait tourner
le système avec la donnée 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 13
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 14
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Oracle
Verdict
On compare le résultat obtenu au résultat attendu : c’est l’oracle.
Dans notre exemple, l’oracle est :
On déduit de l’exécution de l’oracle si le test a réussi ou échoué.
lm.getLevel(7) = Level.Mid
En objet le langage des assertions peut être très riche :
I
expression booléenne
I
levée d’une exception
I
appel d’une méthode sur tel objet avec tel paramètre
(interactions)
I
etc
Mirabelle Nebut
C’est le verdict.
Verdict classique pour une assertion ”booléenne” :
L’oracle est toujours une assertion.
Introduction au test 15
I
elle vaut true : le test passe ;
I
elle vaut false : le test échoue ;
I
il y a une levée d’exception pas prévu : erreur, le test est
inconclusif.
Mirabelle Nebut
Introduction au test 16
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Associer verdict et oracle
Fixture
On aimerait déduire automatiquement le verdict de l’exécution du
test (via l’oracle).
En première approche, avec les moyens du bord :
...
try {
if (lm.getLevel(7) == Level.Mid)
S.O.P("test passe");
else
S.O.P("test échoue");
catch (Exception e) {
S.O.P("erreur, test inconclusif");
}
Mirabelle Nebut
Avant d’exécuter l’oracle, il faut amener l’objet dans un
contexte/état favorable.
Cette préparation du contexte = fixture, installation, setUp ;
Dans notre exemple : création de l’objet et positionnement de son
état
LevelManagement lm = new LevelManagement();
lm.setLevel(2, 10, 20);
try { ... // oracle ...}
Introduction au test 17
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 18
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Cas de test
Suite de tests
L’ensemble du test exécutable 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 échoue");
catch (Exception e) {
S.O.P("erreur, test inconclusif");
}
Mirabelle Nebut
On regroupe les cas de test par suite de tests :
I
collection de cas de tests (abstraits ou exécutables) ;
I
ou collection de suite de tests (abstraits ou exécutables).
Permet de :
I
grouper des tests par concepts
I
lancer des tests par paquets
Introduction au test 19
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Exercice : cas de test
I
en identifiant l’objectif de test (différent du précédent) ;
I
en identifiant la donnée de test ;
I
en identifiant le résultat attendu ;
I
en identifiant l’oracle ;
I
en écrivant la totalité du cas de test exécutable.
Réfléchir à un/des cas de test pour setLevel(int, int, int).
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
JUnit
Écrire un autre test pour getLevel() :
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 20
Framework de test pour Java.
I
Erich Gamma et Kent Beck
I
TDD (test-driven developpment), Xtreme programming, agile
development
I
open source : www.junit.org
I
intégration 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.
Introduction au test 21
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
JUnit 3.8, 4, 4.4, 4.5. . .
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 22
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Ce que JUnit offre
Grand saut entre JUnit3.8 et JUnit4 :
JUnit is designed to efficiently capture developers’ intentions about
their code, and quickly check their code matches those intentions
[junit.org]
I
nouvelle architecture
I
nouvelles fonctionnalités
I
des assertions plus expressives pour exprimer les oracles ;
I
nouveau style : JUnit4 = basé sur annotations Java5
I
la création de suite de tests à grain fin ;
I
plus simple d’utilisation
I
le formatage du verdict, soit graphique, soit textuel ;
I
la possibilité de lancer facilement les tests
I
des fonctionnalités pour écrire des tests toujours plus concis et
lisibles
I
= (presque) tout pour que tester soit plaisant et rapide.
Accélération des implantations de nouvelles fonctionnalités depuis
la v4.
SVL : JUnit4
Ce qu’il n’offre pas : des recettes pour trouver les bons tests !
Mirabelle Nebut
Introduction au test 23
Mirabelle Nebut
Introduction au test 24
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Conventions pour SVL : organisation des sources
Les tests ne sont pas dans le source de l’applicatif !
Le répertoire de travail contient les répertoires (noms au choix) :
I
classes (exécutables) ;
I
src (sources) contenant les paquetages applicatifs ;
I
test (tests) avec les mêmes 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.
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Conventions pour SVL : utiliser Eclipse ?
Vous êtes fan d’Emacs ? moi aussi ! Et pourtant, Eclipse aide à
utiliser 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
. . . plutôt qu’un affichage console genre : ... OK (3 tests)
Pour l’aide dans l’écriture des (import) :
I
nombreux import à écrire, fastidieux à retenir ;
I
Eclipse les suggère.
Pour l’aide à la création des suites de test.
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 25
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 26
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Les assertions de JUnit (base)
Servent à décrire l’oracle du cas de test.
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
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
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 27
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Les assertions de JUnit : fonctionnement
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 28
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemples
Si l’assertion est violée :
I
levée d’une erreur AssertionFailedError
I
l’erreur fait échouer le test
Si l’assertion n’est pas violée : elle termine simplement.
Méthodes définies statiquement dans la classe org.junit.Assert.
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
import static org.junit.Assert.*;
assertSame(Level.Mid, lm.getLevel(7));
assertEquals(10, lm.getHighLevel());
assertTrue(lm.getLowLevel() <= lm.getHighLevel());
Introduction au test 29
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemple : cas des exceptions
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 30
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Message d’erreur
try {
this.lmNominal.getLevel(-1);
fail(); // on ne doit pas passer ici
} catch (OutOfLevelException e) {
// OK
};
assertEquals(lm1,lm2); // 2 objets différents
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 à partir de lm1/2.toString()
Il a plus simple, cf la suite.
⇒ implanter toString() pour les besoins du test
Mirabelle Nebut
Introduction au test 31
Mirabelle Nebut
Introduction au test 32
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Message d’erreur
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Message d’erreur
Si
Toutes les assertions peuvent commencer par un paramètre String
assertEquals(lm1,lm2);
assertEquals(lm1,lm3);
Il sera affiché en cas d’erreur.
produit :
import static org.junit.Assert.*;
java.lang.AssertionError:
expected:... but was:...
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");
on ne sait pas quelle assertion a été violée.
⇒ intégrer des messages dans les assertions
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Peut être très utile, ou alourdir inutilement le code.
Introduction au test 33
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 34
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Classe de test
Qu’est-ce que le test
Ou classe contenant des cas des test (= suite de test).
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Par convention, la classe de test qui teste la classe
levelStuff.LevelManagement (répertoire src) a pour nom
levelStuff.TestLevelManagementBlaBlaBla (répertoire
test).
BlaBlaBla : description informative de la suite de test.
Introduction au test 35
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Classe de test
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 36
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Méthode de test - JUnit4
En JUnit4 : la classe de test est une simple classe Java.
Ou méthode d’une classe de test, représentant un cas de test.
Création sous Eclipse :
I
new JUnit Test Case
I
annotée par @Test ;
I
choisir JUnit 4
I
import org.junit.Test ;
I
éventuellement choisir quelles méthodes doivent être testées.
I
publique, type de retour void ;
I
pas de paramètre, peut lever une exception.
package levelStuff;
public class TestLevelManagement {...}
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 37
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Test JUnit4 : exemple
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 38
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Le verdict de JUnit
@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 équivalent
}
I
le test passe : OK
I
le test échoue : failure
I
exception inattendue : error
Graphiquement :
I
le test passe : barre verte / croix verte Eclipse
I
le test échoue : barre rouge / croix bleue Eclipse
I
erreur : barre rouge / croix rouge Eclipse
Pour lancer ce test sous Eclipse : run as JUnit Test Case ou
run as s’il y a des choses à configurer.
Mirabelle Nebut
Introduction au test 39
Mirabelle Nebut
Introduction au test 40
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Test JUnit4 : autre exemple
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Pour lancer les tests en textuel
Avec le Runner par défaut.
@Test
java org.junit.runner.JUnitCore
public void testGetLevelMidUpperLimit() throws OutOfLevelException {
levelStuff.TestLevelManagement
LevelManagement lmNominal;
JUnit version 4.1
lmNominal = new LevelManagement();
..
lmNominal.setLevel(3, 10, 20);
Time: 0.021
assertSame(Level.Mid,lmNominal.getLevel(10));
}
OK (2 tests)
JUnit permet de lancer les 2 tests d’un coup (on ne sait pas dans
quel ordre).
Si l’un des tests est @Ignore :
Pour ignorer un test : @Ignore (à importer).
.I
Time: 0.021
Sous Eclipse : on peut choisir finement quel test lancer.
OK (1 test)
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 41
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Remarque
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 42
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Fixture JUnit : @Before
import org.junit.Before;
Après l’écriture des 2 tests, on réalise que le code se répète !
Le fixture est logiquement commun à plusieurs tests :
Préambule : méthode annotée par @Before :
I
par convention (héritée de JUnit3.8) appelée setUp ;
I
on réusine ;
I
publique, throws Exception ;
I
on utilise le fixture de JUnit.
I
appelée avant chaque appel d’une méthode de test ;
I
sert à factoriser la construction des objets.
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 43
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
@Before - Exemple
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 44
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
@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 test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Fixture : les autres méthodes associées
Postambule : méthode annotée par @After :
I
par convention (héritée de JUnit3.8) appelée tearDown ;
I
publique, throws Exception ;
I
appelée après chaque appel d’une méthode de test.
Méthodes avec annotations @BeforeClass et @AfterClass :
I
publiques et statiques ;
I
exécutées avant (resp. après) l’appel de la première (resp.
dernière) méthode de test ;
I
une seule méthode pour chaque annotation ;
I
pas en JUnit3.8.
Mirabelle Nebut
Introduction au test 47
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
Assertions
...
Qu’est-ce que le test
Classes et méthodes de test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
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 test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Pour construire une suite de test JUnit
Difficile à mémoriser. . .merci Eclipse !
I utilisation d’un autre runner que celui par défaut, le
org.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
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Remarque - nommage des méthodes de test
Convention :
I
le nom d’une méthode qui teste la méthode getLevel devrait
commencer par testGetLevel ;
I
la suite du nom devrait indiquer l’objectif de test :
testGetLevelOutOfLowerBound,
testGetLevelNominalHigh,etc ;
I
si l’objectif est trop compliqué à expliquer dans le nom du
test : s’inquiéter, ou rajouter un commentaire.
Introduction au test 49
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 50
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Remarque - oracle(s)
Qu’est-ce que le test
Convention : un cas de test contient forcément un oracle.
Certaines écoles imposent un seul oracle par cas de test.
Avantage : assertion clairement identifiée si le test échoue.
Inconvénients :
I
oblige à dupliquer le fixture des tests
I
parfois très artificiel
⇒ tendre à limiter le nombre d’oracle, sans dogmatisme.
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Introduction au test 51
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Les inconvénients du assertEquals
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 52
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Le assertThat
assertThat([actualValue], [matcher statement]);
assertEquals(String message,
Object expected, Object actual)
L’ordre ”expected, actual” n’est pas intuitif.
”j’aimerais que soient égaux ce que j’attends et ce que j’obtiens”
vs
”j’aimerais que ce que j’obtiens soit égal à ça”
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Exemples :
assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(responseString,
either(containsString("color")).
or(containsString("colour")));
assertThat(myList, hasItem("3"));
Introduction au test 53
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Le assertThat
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 54
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Les Matcher fournis
JUnitMatchers :
assertThat([actualValue], [matcher statement]);
Le matcher est de type org.hamcrest.Matcher
I
both, either, containsString, everyItem, hasItem
org.hamcrest.core :
I
Is : is(Class), is(Matcher<t>), is(T)
I
assertThat dans Assert ;
I
IsEqual : equalTo(T) ;
I
classe org.junit.matchers.JUnitMatchers ;
I
IsNot : not(Matcher<t>), not(T) ;
I
paquetage org.hamcrest.core.
I
et d’autres
JUnit ne contient pas tout hamcrest :
Mirabelle Nebut
Introduction au test 55
Mirabelle Nebut
Introduction au test 56
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Avantages
Permet d’écrire ses propres Matcher
Qu’est-ce que le test
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
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Introduction au test 57
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Tests paramétrés (JUnit 4)
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 58
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemple - test paramétré
Test de la méthode int sum (int x, int y) de
paramSum::Sum
Pour factoriser les données de test si combinatoire :
I
écriture séparée des tests (oracle) et des données de test
I
les données incluent le résultat attendu
I
le runner fait le produit en croix des données de test et des
méthodes de test.
package paramSum;
import
import
import
import
import
import
org.junit.Test;
org.junit.runner.RunWith;
org.junit.runners.Parameterized;
org.junit.runners.Parameterized.Parameters;
static org.junit.Assert.*;
java.util.*;
@RunWith(Parameterized.class)
public class TestParamSum { ... }
Mirabelle Nebut
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 59
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemple - test paramétré
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
@Parameters
public static Collection testData() {
return Arrays.asList(new Object[][] {
{ 0, 0, 0 },
{ 1, 1, 2 },
{ 2, 1, 3 },
{10, 9, 19}});
}
public TestParamSum(int x, int y, int res) {
this.x = x;
this.y = y;
this.res = res;
}
Mirabelle Nebut
@Test
public void testSum() {
assertEquals(res,new Sum().sum(x,y));
}
Introduction au test 61
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemple - test paramétré
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 62
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Test paramétré - résumé
> java org.junit.runner.JUnitCore paramSum.TestParamSum
JUnit version 4.1
....
Time: 0.397
OK (4 tests)
Mirabelle Nebut
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Exemple - test paramétré
private int x;
private int y;
private int res;
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Introduction au test 60
Introduction au test 63
I
runner org.junit.runners.Parameterized
I
données fournies par une méthode publique statique qui
retourne une collection et est annotée par @Parameters ;
I
constructeur public pour la classe de test qui prend en
paramètre les données et le résultat attendu ;
Mirabelle Nebut
Introduction au test 64
Qu’est-ce que le test
Qu’est-ce qu’un test : terminologie
Tester avec JUnit
Assertions
Classes et méthodes de test
Assertions version assertThat (JUnit4.4)
Autres fonctionnalités
Assumptions (JUnit4.4)
Permet d’exprimer le contexte dans lequel le test est supposé
passer, 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