{"componentChunkName":"component---src-templates-lecture-template-js","path":"/lectures/semaine10/strategie-test-exercice","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"slug\": \"semaine10/strategie-test-exercice\",\n  \"title\": \"Exercice: monter une stratégie de test\",\n  \"type\": \"exercise\",\n  \"time\": \"45 minutes\"\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar Solution = makeShortcode(\"Solution\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Pour cet exercice, nous allons utiliser une page de cr\\xE9ation de compte.\"), mdx(\"p\", null, \"Voici un wireframe de cette page :\"), mdx(\"p\", null, mdx(\"span\", _extends({\n    parentName: \"p\"\n  }, {\n    \"style\": {\n      \"display\": \"block\",\n      \"width\": \"720px\"\n    }\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1024\",\n      \"margin\": \"0\"\n    }\n  }), \"\\n      \", mdx(\"a\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/19afe15c0a259118470c74a117bd5a94/8ea22/app.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"\\n    \", mdx(\"span\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"61.963190184049076%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"display\": \"block\"\n    }\n  })), \"\\n  \", mdx(\"img\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Image de l'app\",\n    \"title\": \"Image de l'app\",\n    \"src\": \"/static/19afe15c0a259118470c74a117bd5a94/a6d36/app.png\",\n    \"srcSet\": [\"/static/19afe15c0a259118470c74a117bd5a94/222b7/app.png 163w\", \"/static/19afe15c0a259118470c74a117bd5a94/ff46a/app.png 325w\", \"/static/19afe15c0a259118470c74a117bd5a94/a6d36/app.png 650w\", \"/static/19afe15c0a259118470c74a117bd5a94/e548f/app.png 975w\", \"/static/19afe15c0a259118470c74a117bd5a94/8ea22/app.png 1023w\"],\n    \"sizes\": \"(max-width: 650px) 100vw, 650px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  })), \"\\n  \"), \"\\n    \"))), mdx(\"p\", null, \"Pour les fins de l'exercice, imaginons que nous avons un front-end tr\\xE8s minimaliste. Le JavaScript\\nde la page ne fait que prendre les 3 champs et les envoyer au back-end via un API rest. Il n'y a aucune\\nvalidation faite en JavaScript. Selon la r\\xE9ponse du back-end, 2 choses peuvent se produire :\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Un succ\\xE8s, alors on redirige l'utilisateur sur la page \", mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://website.com/login\"\n  }), \"https://website.com/login\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Une erreur, alors on affiche le message d'erreur \\xE0 l'endroit pr\\xE9vu.\")), mdx(\"p\", null, \"Voici les crit\\xE8res d'acceptations qui ont \\xE9t\\xE9 \\xE9crits par le PO:\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Crit\\xE8re\"), mdx(\"th\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"D\\xE9finition\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 1\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Si un des champs est manquant, l'erreur \\\"Tous les champs sont requis\\\" est affich\\xE9e\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 2\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Si le \", mdx(\"code\", _extends({\n    parentName: \"td\"\n  }, {\n    \"className\": \"language-text\"\n  }), \"username\"), \" est d\\xE9j\\xE0 pris, alors l'erreur \\\"Ce username est d\\xE9j\\xE0 pris\\\" est affich\\xE9e\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 3\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Si les 2 \", mdx(\"code\", _extends({\n    parentName: \"td\"\n  }, {\n    \"className\": \"language-text\"\n  }), \"password\"), \" ne correspondent pas, l'erreur \\\"Les passwords ne concordent pas` est affich\\xE9e\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 4\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Si le mot de passe ne contient pas au minimum 8 caract\\xE8res dont 1 symbole, alors on affiche \\\"Password invalid\\\"\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 5\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Apr\\xE8s la cr\\xE9ation du compte (succ\\xE8s seulement), l'utilisateur est redirig\\xE9 vers \", mdx(\"a\", _extends({\n    parentName: \"td\"\n  }, {\n    \"href\": \"https://website.com/login\"\n  }), \"https://website.com/login\"))), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 6\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Le compte est persist\\xE9 \", \"*\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"COS 7\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": null\n  }), \"Un courriel est envoy\\xE9 \\xE0 \", mdx(\"a\", _extends({\n    parentName: \"td\"\n  }, {\n    \"href\": \"mailto:admin@website.com\"\n  }), \"admin@website.com\"), \" lorsqu'un compte est cr\\xE9\\xE9, avec le username choisit\")))), mdx(\"p\", null, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), \"*\"), \" Ce crit\\xE8re n'est pas excellent, id\\xE9alement \\\"L'utilisateur peut s'authentifier avec son nouveau compte\\\" serait mieux, mais\\nafin de r\\xE9duire la port\\xE9e de cet exercice, on va consid\\xE9rer le COS 6 comme correct.\"), mdx(\"p\", null, \"La communication entre le front-end et le back-end se fait via un API rest :\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"httprequest\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"style\": {\n      \"counterReset\": \"linenumber NaN\"\n    },\n    \"className\": \"language-httprequest line-numbers\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-httprequest\"\n  }), \"POST /accounts\\nContent-Type: application/json\\n\\n{\\n    \\\"username\\\": \\\"??\\\",\\n    \\\"password\\\": \\\"??\\\",\\n    \\\"password_confirmation: \\\"??\\\"\\n}\"), mdx(\"span\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"className\": \"line-numbers-rows\",\n    \"style\": {\n      \"whiteSpace\": \"normal\",\n      \"width\": \"auto\",\n      \"left\": \"0\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  })))), mdx(\"p\", null, \"Et la r\\xE9ponse est la suivante :\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"json\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"style\": {\n      \"counterReset\": \"linenumber NaN\"\n    },\n    \"className\": \"language-json line-numbers\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-json\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), \"{\"), \"\\n  \", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), \"\\\"success\\\"\"), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token operator\"\n  }), \":\"), \" \", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token boolean\"\n  }), \"true\"), \" | \", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token boolean\"\n  }), \"false\"), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), \",\"), \"\\n  \", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), \"\\\"error_message\\\"\"), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token operator\"\n  }), \":\"), \" \", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token null keyword\"\n  }), \"null\"), \" | string\\n\", mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), \"}\")), mdx(\"span\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"aria-hidden\": \"true\",\n    \"className\": \"line-numbers-rows\",\n    \"style\": {\n      \"whiteSpace\": \"normal\",\n      \"width\": \"auto\",\n      \"left\": \"0\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  })))), mdx(\"h2\", null, \"Question 1\"), mdx(\"p\", null, \"Pour chacun des COS ci-haut, nous voudrions avoir un ou plusieurs tests fonctionnels pour tester ces crit\\xE8res.\"), mdx(\"p\", null, \"\\xC0 quel niveau placeriez-vous chacun d'entre eux afin de respecter la pyramide de tests?\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Manuel (qui ne fait pas partie de la pyramide, mais qui est tout de m\\xEAme n\\xE9cessaire)\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Large\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Medium\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Small\")), mdx(Solution, {\n    mdxType: \"Solution\"\n  }, mdx(\"p\", null, \"Il y a plus de tests que de COS ici, et c'est voulu! C'est pour permettre un boulonnage des tests, ceci est expliqu\\xE9 plus bas.\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que les champs sont pr\\xE9sents (COS 1) peut se faire via un test small ou medium (si on prend un framework de validation)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que l'erreur est affich\\xE9e (COS 1 \\xE0 4), peut importe l'erreur, peut \\xEAtre un test small en javascript\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le back-end retourne les bonnes r\\xE9ponses d'API peut \\xEAtre un test m\\xE9dium (COS 1 \\xE0 4)\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Il est possible de faire cela en d\\xE9marrant le serveur, mais en lui injectant une doublure du service applicatif, afin de contr\\xF4ler les r\\xE9ponses\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le formulaire est bien envoy\\xE9 peut \\xEAtre un test small en JavaScript (qui s'ex\\xE9cute sans le back-end) (COS 1 \\xE0 4)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le username n'est pas pris (COS 2) peut \\xEAtre un test small\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le password et la confirmation concorde peut \\xEAtre au niveau small (COS 3)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le password respecte les r\\xE8gles de s\\xE9curit\\xE9 peut \\xEAtre un test small (COS 4)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider la redirection peut \\xEAtre un test small au front-end (COS 5)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le compte est persist\\xE9 peut \\xEAtre un test medium entre le repository et la BD (en m\\xE9moire ou non) (COS 6)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider que le email est bien \\xE9crit (avec le username dedans) peut \\xEAtre un test small (valide seulement le contenu) (COS 7)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Valider l'envoie du email pourrait \\xEAtre un test manuel dans bien des cas, si nous n'avons pas d'autres fa\\xE7ons. Il existe des outils qui permettent\\nde faire des tests medium pour l'envoie d'email, mais ce n'est pas toujours possible.\")), mdx(\"p\", null, \"Total:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Manuel: 1\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Large: 0\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Medium: 2\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Small: 8\")), mdx(\"p\", null, \"Le probl\\xE8me avec cette solution qui minimise tous les types de tests, c'est qu'aucun ne fait le bout-en-bout. Nous n'avons\\nrien qui permet de tester la \\\"colle\\\" entre les morceaux (la configuration, l'injection des d\\xE9pendances, le bon format de la\\nbase de donn\\xE9es, int\\xE9gration entre le front-end et le back-end, etc). Dans une application vraiment simple, ces tests pourraient\\n\\xEAtre inutiles, mais pr\\xE9sumons ici que nous sommes dans une application plus complexe et qu'il serait souhaitable de faire ce test.\"), mdx(\"p\", null, \"Une strat\\xE9gie possible, afin de ne pas dupliquer de tests, pourrait \\xEAtre d'en \\\"\\xE9lire\\\" un qui sera ex\\xE9cut\\xE9 \\xE0 plus haut niveau. Il est\\ntypiquement plus simple de prendre le \\\"happy path\\\" pour cela. Ici, on pourrait dire que le test qui sert \\xE0 valider qu'il y a une\\nredirection apr\\xE8s la cr\\xE9ation du compte serait un test large. Dans ce cas, celui-ci se ferait en d\\xE9marrant le serveur et en passant\\npar le front-end afin de faire une boucle compl\\xE8te. Nous aurions donc au total :\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Manuel: 1\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Large: 1\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Medium: 2\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Small: 7\")), mdx(\"p\", null, \"Ce qui correspond bien aux ratios demand\\xE9s par la pyramide de test.\"), mdx(\"p\", null, \"Notez que le \\\"boulonnage\\\" des tests est la cl\\xE9 ici. Puisque j'ai un test en javascript qui s'assure que le formulaire est\\nsoumis correctement, et que j'ai un test medium qui s'assure que l'API r\\xE9pond correctement au contrat, alors je n'ai pas besoin\\nd'avoir un test large pour chacun des COS.\"), mdx(\"p\", null, \"Il s'agit d'un pattern fr\\xE9quent: je valide que l'utilisateur du contrat l'utilise correctement, et ensuite que l'ex\\xE9cuteur du\\ncontrat remplit sa t\\xE2che correctement. De cette fa\\xE7on, chaque c\\xF4t\\xE9 du contrat peut changer comme bon lui semble sans affecter\\ntous les tests, ce qui ajoute de la flexibilit\\xE9 et rend les tests moins fragiles.\")), mdx(\"h2\", null, \"Question 2\"), mdx(\"p\", null, \"Nous avons maintenant r\\xE9pondus aux crit\\xE8res d'acceptation demand\\xE9s par le client. Par contre, nous n'avons pas fini!\"), mdx(\"p\", null, \"Seriez-vous r\\xE9ellement confiant de livrer en production, les yeux ferm\\xE9s, \\xE0 16h un vendredi soir avec les tests ci-haut?\"), mdx(\"p\", null, \"Bien que nos tests respectent la pyramide, nous n'avons pas vraiment regard\\xE9 le quadrant de tests :\"), mdx(\"p\", null, mdx(\"span\", _extends({\n    parentName: \"p\"\n  }, {\n    \"style\": {\n      \"display\": \"block\",\n      \"width\": \"480px\"\n    }\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1024\",\n      \"margin\": \"0\"\n    }\n  }), \"\\n      \", mdx(\"a\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/85893ccd8e31835a7cf78f108d306f3d/9cb4e/quadrant.png\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }), \"\\n    \", mdx(\"span\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"95.0920245398773%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"display\": \"block\"\n    }\n  })), \"\\n  \", mdx(\"img\", _extends({\n    parentName: \"a\"\n  }, {\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"quadrant\",\n    \"title\": \"quadrant\",\n    \"src\": \"/static/85893ccd8e31835a7cf78f108d306f3d/9cb4e/quadrant.png\",\n    \"srcSet\": [\"/static/85893ccd8e31835a7cf78f108d306f3d/222b7/quadrant.png 163w\", \"/static/85893ccd8e31835a7cf78f108d306f3d/ff46a/quadrant.png 325w\", \"/static/85893ccd8e31835a7cf78f108d306f3d/9cb4e/quadrant.png 431w\"],\n    \"sizes\": \"(max-width: 431px) 100vw, 431px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  })), \"\\n  \"), \"\\n    \"))), mdx(\"p\", null, \"Pour chacun des 4 quadrants, \\xE9crivez les autres tests qui seraient pertinents de faire.\"), mdx(Solution, {\n    mdxType: \"Solution\"\n  }, mdx(\"h3\", null, \"Q1\"), mdx(\"p\", null, \"Pour le premier quadrant, il s'agit simplement de tous les tests unitaires qu'un d\\xE9veloppeur ferait normalement. Certains\\nseront doublement consid\\xE9r\\xE9s comment \\xE9tant des tests d'acceptations \\xE9galement (ceux de la question 1), mais c'est bien correct.\"), mdx(\"p\", null, \"D'autres exemples seraient un test de contexte (s'assurer que l'app d\\xE9marre et lit les bonnes configurations, par exemple).\"), mdx(\"p\", null, \"Certains auteurs ajouteraient \\xE9galement ici des tests d'API (format, protocol, etc).\"), mdx(\"h3\", null, \"Q2\"), mdx(\"p\", null, \"Les tests de la question 1 vont ici, donc nous avons pas mal couvert ce quadrant!\"), mdx(\"h3\", null, \"Q3\"), mdx(\"p\", null, \"Notre page \\xE9tant une cr\\xE9ation de compte tr\\xE8s standard, il n'est pas vraiment pertinent de faire des tests utilisateurs. Une\\nd\\xE9mo au PO serait s\\xFBrement suffisant!\"), mdx(\"p\", null, \"Dans certains cas nous pourrions ici vouloir mesurer des m\\xE9triques applications et comportementales (taux d'\\xE9chec, temps de r\\xE9ponse, etc).\"), mdx(\"h3\", null, \"Q4\"), mdx(\"p\", null, \"La premi\\xE8re chose que je testerais ici c'est la s\\xE9curit\\xE9! Est-ce que la page est vuln\\xE9rable aux injections SQL?\"), mdx(\"p\", null, \"Un autre cas int\\xE9ressant ici pourrait \\xEAtre des \\\"smoke tests\\\", o\\xF9 on bombarde l'application de cr\\xE9ation de compte. En autre, il\\nserait int\\xE9ressant de tester des \\\"race conditions\\\" o\\xF9 plusieurs personnes prennent le m\\xEAme nom d'utilisateur.\"), mdx(\"p\", null, \"Ensuite, des tests de charge pourraient \\xEAtre int\\xE9ressant si l'application sera d\\xE9ploy\\xE9e \\xE0 un grand nombre d'utilisateurs.\")));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"slug":"semaine10/strategie-test-exercice","title":"Exercice: monter une stratégie de test","type":"exercise","time":"45 minutes"}}},"pageContext":{"slug":"semaine10/strategie-test-exercice","previous":"/lectures/semaine10/type-portee-exercices","next":null,"breadcrumbs":[{"url":"/curriculum","label":"Curriculum"},{"label":"Semaine 10"},{"label":"Tests non unitaires"},{"url":"/lectures/semaine10/strategie-test-exercice","label":"Exercice: monter une stratégie de test"}]}}}