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