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 Introduction au test 1
65
Embed
SVL - Cours-TD 1 Introduction au test du logiciel Premiers ... · Introduction au test du logiciel Premiers pas avec JUnit Mirabelle Nebut Bureau 332 - M3 mirabelle.nebut at lifl.fr
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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
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