{"id":492,"date":"2021-11-22T18:22:01","date_gmt":"2021-11-22T18:22:01","guid":{"rendered":"https:\/\/www.louismarchand.me\/?page_id=492"},"modified":"2021-11-22T18:23:25","modified_gmt":"2021-11-22T18:23:25","slug":"objet2-les-tests-unitaires","status":"publish","type":"page","link":"https:\/\/www.louismarchand.me\/index.php\/objet2-les-tests-unitaires\/","title":{"rendered":"Les tests unitaires"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>Un des \u00e9l\u00e9ments les plus importants dans le d\u00e9veloppement d&rsquo;un logiciel est le test des diff\u00e9rentes fonctionnalit\u00e9s de ce dernier. Les limites trop serr\u00e9es de date limite de d\u00e9veloppement et l&rsquo;aspect un peu r\u00e9p\u00e9titif et peu agr\u00e9able du d\u00e9veloppement des tests font en sorte que, malheureusement, le d\u00e9veloppement de tests est souvent laiss\u00e9 pour compte. Il s&rsquo;agit n\u00e9anmoins d&rsquo;une \u00e9tape capitale au d\u00e9veloppement d&rsquo;un logiciel fiable et robuste.<\/p>\n<p>On a souvent une version tr\u00e8s limit\u00e9e de l&rsquo;utilisation des tests. Tout programmeur comprendra que les tests doivent:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Valider ce que l&rsquo;application fait;<\/li>\n<li>Permets de d\u00e9tecter des \u00ab\u00a0bugs\u00a0\u00bb dans le programme<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Par contre, les tests permettent \u00e9galement de:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Documenter les classes\n<ul>\n<li>Indiquer les limites de ces classes<\/li>\n<\/ul>\n<\/li>\n<li>Pr\u00e9voir l&rsquo;\u00e9criture des modules du programme\n<ul>\n<li>En effet, le \u00ab\u00a0Test Driven Developpement\u00a0\u00bb consiste \u00e0 \u00e9crire les tests des modules avant que ces modules soient cr\u00e9\u00e9s.<\/li>\n<\/ul>\n<\/li>\n<li>L&rsquo;application ne fait pas ce qu&rsquo;elle n&rsquo;est pas cens\u00e9e faire\n<ul>\n<li>En d&rsquo;autres mots, que l&rsquo;application fait ce qu&rsquo;elle est cr\u00e9\u00e9e pour faire, et rien d&rsquo;autre<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Les diff\u00e9rents types de tests<\/h2>\n<p>Il existe plusieurs types de tests qui permettent de valider diff\u00e9rents aspects du logiciel. Les plus courants sont les tests suivants:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Tests unitaires (parfois appel\u00e9 \u00ab\u00a0White Box Testing\u00a0\u00bb):\n<ul>\n<li>Permet de tester individuellement les modules de programmation. En programmation orient\u00e9e objet par classes, les modules de programmation sont les classes en tant que telles.<\/li>\n<li>Dans les tests unitaires, le test conna\u00eet la structure (et non le code pr\u00e9cis des m\u00e9thodes) de la classe et l&rsquo;utilise afin de valider chacune de ses fonctionnalit\u00e9s.<\/li>\n<\/ul>\n<\/li>\n<li>Tests de non-r\u00e9gression (parfois appel\u00e9 \u00ab\u00a0Black Box Testing\u00a0\u00bb):\n<ul>\n<li>Ce type de tests permet de valider l&rsquo;exp\u00e9rience utilisateur;<\/li>\n<li>Valide l&rsquo;interface et les valeurs visibles par l&rsquo;utilisateur;<\/li>\n<li>Le test doit prendre en compte ce que le logiciel doit faire, et non la structure des classes;<\/li>\n<li>Ce type de tests ne n\u00e9cessite pas l&rsquo;utilisation de la programmation. Par exemple, un adjoint administratif pourrait effectuer ces tests.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>On appelle Tests syst\u00e8me l&rsquo;ensemble de tous les tests (unitaire et de non-r\u00e9gression) du syst\u00e8me.<\/p>\n<p>On appelle une suite de tests l&rsquo;ensemble des tests s&rsquo;appliquant \u00e0 une partie de logiciel. Par exemple, on pourrait avoir une suite de tests pour une m\u00e9thode, pour une classe ou pour un logiciel.<\/p>\n<p>Dans le cadre du cours, nous allons voir l&rsquo;utilisation des tests unitaires.<\/p>\n<h2>Les tests unitaires<\/h2>\n<p>Dans un contexte objet, une suite de tests d&rsquo;un test unitaire doit permettre de tester le maximum de fonctionnalit\u00e9s d&rsquo;une classe. En g\u00e9n\u00e9ral, on ne teste pas les proc\u00e9dures effectuant des entr\u00e9es\/sorties (lecture au clavier, \u00e9criture \u00e0 l&rsquo;\u00e9cran, sauvegarde de fichier, etc.), mais ce n&rsquo;est pas une r\u00e8gle absolue. S&rsquo;il est possible de tester une m\u00e9thode sans trop de difficult\u00e9, il est pr\u00e9f\u00e9rable de le faire. Les tests d&rsquo;une s\u00e9rie de tests doivent comprendre les types de cas suivants:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Cas normaux:\n<ul>\n<li>Repr\u00e9sentent des cas qui permettent de valider que la m\u00e9thode fait le travail qu&rsquo;elle est sens\u00e9e faire;<\/li>\n<li>G\u00e9n\u00e9ralement les cas les plus simples \u00e0 tester;<\/li>\n<li>Souvent, il s&rsquo;agit du seul type de cas utilis\u00e9s par les programmeurs plus \u00ab\u00a0hatif\u00a0\u00bb.<\/li>\n<\/ul>\n<\/li>\n<li>Cas erron\u00e9s:\n<ul>\n<li>Repr\u00e9sente des cas qui n&rsquo;est pas sens\u00e9 \u00eatre trait\u00e9 par la m\u00e9thode;<\/li>\n<li>Permet de valider la validation d&rsquo;exceptions dans la m\u00e9thode:\n<ul>\n<li>Dans la plupart des langages, test l&rsquo;utilisation des exceptions style throw.<\/li>\n<li>En Eiffel, \u00e7a permet de v\u00e9rifier que les pr\u00e9conditions sont bien construits.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Cas limites:\n<ul>\n<li>Repr\u00e9sente les premi\u00e8res valeurs repr\u00e9sent\u00e9es comme normales ou erron\u00e9es.<\/li>\n<li>G\u00e9n\u00e9ralement les cas les plus difficiles \u00e0 trouver;<\/li>\n<li>Ce n&rsquo;est pas toutes les m\u00e9thodes qui ont des cas limites\n<ul>\n<li>Par exemple, pour indexer une liste en Java, nous aurions quatre (4) cas limites:\n<ul>\n<li>0 qui repr\u00e9sente le premier cas normal;<\/li>\n<li>-1 qui repr\u00e9sente le dernier cas erron\u00e9 (avant 0)<\/li>\n<li>\u00ab\u00a0Taille de la liste -1\u00a0\u00bb qui repr\u00e9sente le dernier cas normal<\/li>\n<li>\u00ab\u00a0Taille de la liste\u00a0\u00bb qui repr\u00e9sente le premier cas erron\u00e9 apr\u00e8s la \u00ab\u00a0Taille de la liste -1\u00a0\u00bb<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Exemples<\/h2>\n<p>Pour vous permettre de bien comprendre la m\u00e9canique, je vais donner un exemple de test unitaire pour un cas normal, erron\u00e9 et limite en Java et Eiffel.<\/p>\n<p>Les tests suivants s&rsquo;appliquent \u00e0 la m\u00e9thode permettant de lire un \u00e9l\u00e9ment dans une liste (<a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/List.html#get(int)\">en Java<\/a> et <a href=\"https:\/\/www.eiffelgame2.org\/Documentation\/elks\/list_flatshort.html#f_at\">en Eiffel<\/a>).<\/p>\n<h3>Cas normaux<\/h3>\n<p>Voici un exemple de cas normal o\u00f9 nous utilisons une liste de 5 \u00e9l\u00e9ments et que nous utilisons l&rsquo;index du second \u00e9l\u00e9ment.<\/p>\n<p>En Eiffel:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">test_at_normal<\/span>\r\n\t\t<span class=\"c1\">-- Test normal pour {LIST}.`at'<\/span>\r\n\t<span class=\"kr\">note<\/span>\r\n\t\t<span class=\"n\">testing<\/span><span class=\"p\">:<\/span>  <span class=\"s\">\"covers\/{LIST}.at\"<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">:<\/span><span class=\"nc\">LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kr\">create<\/span> <span class=\"p\">{<\/span><span class=\"nc\">LINKED_LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span><span class=\"p\">}<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">assert<\/span><span class=\"p\">(<\/span><span class=\"s\">\"{LIST}.at(2) valide\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">at<\/span> <span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>En Java:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"nd\">@Test<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">testGetNormal<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">lListe<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">LinkedList<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertEquals<\/span><span class=\"p\">(<\/span><span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">get<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">).<\/span><span class=\"na\">intValue<\/span><span class=\"p\">(),<\/span> <span class=\"mi\">2<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/pre>\n<\/div>\n<h3>Cas erron\u00e9s<\/h3>\n<p>Voici un exemple de cas erron\u00e9 o\u00f9 nous utilisons la m\u00eame liste de 5 \u00e9l\u00e9ments et que nous utilisons l&rsquo;index 10, qui est \u00e0 l&rsquo;ext\u00e9rieur de cette liste.<\/p>\n<p>En Eiffel:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">test_at_errone<\/span>\r\n\t\t<span class=\"c1\">-- Test erron\u00e9 pour {LIST}.`at'<\/span>\r\n\t<span class=\"kr\">note<\/span>\r\n\t\t<span class=\"n\">testing<\/span><span class=\"p\">:<\/span>  <span class=\"s\">\"covers\/{LIST}.at\"<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_retry<\/span><span class=\"p\">:<\/span><span class=\"nc\">BOOLEAN<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">:<\/span><span class=\"nc\">LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span>\r\n\t\t<span class=\"n\">l_valeur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kr\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">l_retry<\/span> <span class=\"kr\">then<\/span>\r\n\t\t\t<span class=\"kr\">create<\/span> <span class=\"p\">{<\/span><span class=\"nc\">LINKED_LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span><span class=\"p\">}<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_valeur<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">at<\/span> <span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">assert<\/span><span class=\"p\">(<\/span><span class=\"s\">\"{LIST}.at erron\u00e9 valide\"<\/span><span class=\"p\">,<\/span> <span class=\"kc\">False<\/span><span class=\"p\">)<\/span> <span class=\"c1\">-- N'est jamais sens\u00e9 se rendre ici<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">rescue<\/span>\r\n\t\t<span class=\"kr\">if<\/span> <span class=\"kr\">attached<\/span> <span class=\"p\">{<\/span><span class=\"nc\">PRECONDITION_VIOLATION<\/span><span class=\"p\">}<\/span> <span class=\"p\">{<\/span><span class=\"nc\">EXCEPTIONS<\/span><span class=\"p\">}.<\/span><span class=\"n\">exception_manager<\/span><span class=\"p\">.<\/span><span class=\"n\">last_exception<\/span> <span class=\"kr\">as<\/span>\r\n\t\t\t<span class=\"n\">la_exception<\/span> <span class=\"ow\">and then<\/span> <span class=\"n\">la_exception<\/span><span class=\"p\">.<\/span><span class=\"n\">type_name<\/span> <span class=\"o\">~<\/span> <span class=\"kc\">Current<\/span><span class=\"p\">.<\/span><span class=\"n\">generating_type<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span>\r\n\t\t<span class=\"kr\">then<\/span>\r\n\t\t\t<span class=\"n\">l_retry<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">True<\/span>\r\n\t\t\t<span class=\"kr\">retry<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>La clause \u00ab\u00a0rescue\u00a0\u00bb sert en gros \u00e0 la m\u00eame chose qu&rsquo;un \u00ab\u00a0try&#8230;catch\u00a0\u00bb en Java. En gros, si un appel de m\u00e9thode effectue une exception lors de l&rsquo;ex\u00e9cution, le code branche directement dans la clause \u00ab\u00a0rescue\u00a0\u00bb. Si le code se termine dans la clause \u00ab\u00a0rescue\u00a0\u00bb, le test est consid\u00e9r\u00e9 comme ayant \u00e9chou\u00e9. C&rsquo;est la raison pour laquelle on effectue un \u00ab\u00a0retry\u00a0\u00bb, qui relance la m\u00e9thode (sans modifier la variable \u00ab\u00a0l_retry\u00a0\u00bb) de mani\u00e8re \u00e0 ce que la m\u00e9thode termine correctement. Ce \u00ab\u00a0retry\u00a0\u00bb est lanc\u00e9 seulement si la m\u00e9thode \u00e9choue avec une pr\u00e9condition, ce qui indique que la m\u00e9thode g\u00e8re correctement l&rsquo;utilisation d&rsquo;un mauvais index.<\/p>\n<p>Sachez que le code suivant fonctionne tout le temps, pour valider les cas erron\u00e9s. Vous pouvez donc utiliser directement ce code, en changeant seulement ce qui est \u00e0 l&rsquo;int\u00e9rieur du \u00ab\u00a0if not l_retry then\u00a0\u00bb.<\/p>\n<p>En Java:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"nd\">@Test<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">testGetErrone<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">lListe<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">LinkedList<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"k\">try<\/span><span class=\"p\">{<\/span>\r\n        <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">get<\/span><span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">);<\/span>\r\n        <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertTrue<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span><span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"n\">IndexOutOfBoundsException<\/span> <span class=\"n\">exception<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"p\">}<\/span><span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"n\">Exception<\/span> <span class=\"n\">exception<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertTrue<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/pre>\n<\/div>\n<h3>Cas limites normaux<\/h3>\n<p>Voici un exemple de cas limite normal o\u00f9 nous utilisons une liste de 5 \u00e9l\u00e9ments et que nous utilisons l&rsquo;index du premier \u00e9l\u00e9ment. Le premier \u00e9l\u00e9ment est le premier index valide des cas normaux. C&rsquo;est donc un cas limite.<\/p>\n<p>En Eiffel:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">test_at_limite_normal<\/span>\r\n\t\t<span class=\"c1\">-- Test limite normal pour {LIST}.`at'<\/span>\r\n\t<span class=\"kr\">note<\/span>\r\n\t\t<span class=\"n\">testing<\/span><span class=\"p\">:<\/span>  <span class=\"s\">\"covers\/{LIST}.at\"<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">:<\/span><span class=\"nc\">LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kr\">create<\/span> <span class=\"p\">{<\/span><span class=\"nc\">LINKED_LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span><span class=\"p\">}<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">assert<\/span><span class=\"p\">(<\/span><span class=\"s\">\"{LIST}.at(2) valide\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">at<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>En Java:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"nd\">@Test<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">testGetNormalLimite<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">lListe<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">LinkedList<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertEquals<\/span><span class=\"p\">(<\/span><span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">get<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">).<\/span><span class=\"na\">intValue<\/span><span class=\"p\">(),<\/span> <span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/pre>\n<\/div>\n<h3>Cas limites erron\u00e9s<\/h3>\n<p>Voici un exemple de cas limite erron\u00e9 o\u00f9 nous utilisons une liste de 5 \u00e9l\u00e9ments et que nous utilisons l&rsquo;index du premier \u00e9l\u00e9ment. Le premier \u00e9l\u00e9ment est le premier index valide des cas normaux. C&rsquo;est donc un cas limite.<\/p>\n<p>En Eiffel:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">test_at_limite_errone<\/span>\r\n\t\t<span class=\"c1\">-- Test limite erron\u00e9 pour {LIST}.`at'<\/span>\r\n\t<span class=\"kr\">note<\/span>\r\n\t\t<span class=\"n\">testing<\/span><span class=\"p\">:<\/span>  <span class=\"s\">\"covers\/{LIST}.at\"<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_retry<\/span><span class=\"p\">:<\/span><span class=\"nc\">BOOLEAN<\/span>\r\n\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">:<\/span><span class=\"nc\">LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span>\r\n\t\t<span class=\"n\">l_valeur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kr\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">l_retry<\/span> <span class=\"kr\">then<\/span>\r\n\t\t\t<span class=\"kr\">create<\/span> <span class=\"p\">{<\/span><span class=\"nc\">LINKED_LIST<\/span><span class=\"o\">[<\/span><span class=\"nc\">INTEGER<\/span><span class=\"o\">]<\/span><span class=\"p\">}<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">extend<\/span> <span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">l_valeur<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_liste<\/span><span class=\"p\">.<\/span><span class=\"n\">at<\/span> <span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">assert<\/span><span class=\"p\">(<\/span><span class=\"s\">\"{LIST}.at limite erron\u00e9 valide\"<\/span><span class=\"p\">,<\/span> <span class=\"kc\">False<\/span><span class=\"p\">)<\/span> <span class=\"c1\">-- N'est jamais sens\u00e9 se rendre ici<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">rescue<\/span>\r\n\t\t<span class=\"kr\">if<\/span> <span class=\"kr\">attached<\/span> <span class=\"p\">{<\/span><span class=\"nc\">PRECONDITION_VIOLATION<\/span><span class=\"p\">}<\/span> <span class=\"p\">{<\/span><span class=\"nc\">EXCEPTIONS<\/span><span class=\"p\">}.<\/span><span class=\"n\">exception_manager<\/span><span class=\"p\">.<\/span><span class=\"n\">last_exception<\/span> <span class=\"kr\">as<\/span>\r\n\t\t\t<span class=\"n\">la_exception<\/span> <span class=\"ow\">and then<\/span> <span class=\"n\">la_exception<\/span><span class=\"p\">.<\/span><span class=\"n\">type_name<\/span> <span class=\"o\">~<\/span> <span class=\"kc\">Current<\/span><span class=\"p\">.<\/span><span class=\"n\">generating_type<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span>\r\n\t\t<span class=\"kr\">then<\/span>\r\n\t\t\t<span class=\"n\">l_retry<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">True<\/span>\r\n\t\t\t<span class=\"kr\">retry<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>En Java:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"nd\">@Test<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">testGetErroneLimite<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">lListe<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">LinkedList<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">add<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">Integer<\/span><span class=\"p\">(<\/span><span class=\"mi\">5<\/span><span class=\"p\">));<\/span>\r\n    <span class=\"k\">try<\/span><span class=\"p\">{<\/span>\r\n        <span class=\"n\">lListe<\/span><span class=\"p\">.<\/span><span class=\"na\">get<\/span><span class=\"p\">(<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\r\n        <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertTrue<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span><span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"n\">IndexOutOfBoundsException<\/span> <span class=\"n\">exception<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"p\">}<\/span><span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"n\">Exception<\/span> <span class=\"n\">exception<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">Assert<\/span><span class=\"p\">.<\/span><span class=\"na\">assertTrue<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/pre>\n<\/div>\n<h2>Outils de tests unitaires<\/h2>\n<p>Les outils de tests unitaires permettent d&rsquo;automatiser l&rsquo;ex\u00e9cution des tests. Ce type d&rsquo;outil est tr\u00e8s int\u00e9ressant, car ils permettent d&rsquo;ex\u00e9cuter rapidement et efficacement les tests unitaires du syst\u00e8me entier, n&rsquo;importe quand. Ce type d&rsquo;outil permet g\u00e9n\u00e9ralement de:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\u00c9crire des tests;<\/li>\n<li>Lancer des tests;<\/li>\n<li>Avoir rapidement acc\u00e8s au rapport d&rsquo;ex\u00e9cution des tests;<\/li>\n<li>Planifier l&rsquo;ex\u00e9cution automatique des tests<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>La majorit\u00e9 des langages ont des outils de tests unitaires automatis\u00e9s (par exemple: Junit, PHPunit, Auto test d&rsquo;EiffelStudio, etc.)<\/p>\n<p>G\u00e9n\u00e9ralement, on aime ex\u00e9cuter l&rsquo;enti\u00e8ret\u00e9 des tests lorsque:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>On a termin\u00e9 une fonctionnalit\u00e9 importante et on s&rsquo;appr\u00eate \u00e0 faire une soumission sur notre d\u00e9p\u00f4t de gestion de version (par exemple, git);<\/li>\n<li>On a effectu\u00e9 un \u00ab\u00a0merge\u00a0\u00bb de plusieurs branches sur notre d\u00e9p\u00f4t de gestion de version et on doit le soumettre officiellement;<\/li>\n<li>On doit cr\u00e9er une \u00ab\u00a0release\u00a0\u00bb finale (envoyer l&rsquo;ex\u00e9cutable sur le site web de la compagnie par exemple).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>R\u00e9f\u00e9rences<\/h2>\n<p>Voici la r\u00e9f\u00e9rence de Eiffel AutoTest: <a href=\"https:\/\/www.eiffel.org\/doc\/eiffelstudio\/AutoTest\">https:\/\/www.eiffel.org\/doc\/eiffelstudio\/AutoTest<\/a><\/p>\n<p>Explication d&rsquo;utilisation de Eiffel AutoTest: <a href=\"https:\/\/www.eiffel.org\/doc\/eiffelstudio\/Using_AutoTest\">https:\/\/www.eiffel.org\/doc\/eiffelstudio\/Using_AutoTest<\/a><\/p>\n<p><a href=\"https:\/\/www.louismarchand.me\/index.php\/les-cours\/programmation-orientee-objet-2\/\">Retour<\/a><\/p>\n<hr \/>\n<p>Auteur: Louis Marchand<br \/>\n<a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/i.creativecommons.org\/l\/by\/4.0\/80x15.png\" alt=\"Creative Commons License\" \/><\/a><br \/>\nSauf pour les sections sp\u00e9cifi\u00e9es autrement, ce travail est sous licence <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\">Creative Commons Attribution 4.0 International<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Un des \u00e9l\u00e9ments les plus importants dans le d\u00e9veloppement d&rsquo;un logiciel est le test des diff\u00e9rentes fonctionnalit\u00e9s de ce dernier. Les limites trop serr\u00e9es de date limite de d\u00e9veloppement et l&rsquo;aspect un peu r\u00e9p\u00e9titif et peu agr\u00e9able du d\u00e9veloppement des tests font en sorte que, malheureusement, le d\u00e9veloppement de tests est souvent laiss\u00e9 pour&hellip; <a class=\"more-link\" href=\"https:\/\/www.louismarchand.me\/index.php\/objet2-les-tests-unitaires\/\">Continue reading <span class=\"screen-reader-text\">Les tests unitaires<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-492","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/comments?post=492"}],"version-history":[{"count":1,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/492\/revisions"}],"predecessor-version":[{"id":493,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/492\/revisions\/493"}],"wp:attachment":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/media?parent=492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}