{"title":"Outils de test","version":"3.2","locale":"fr","docname":"topics/testing/tools","url":"/fr/3.2/topics/testing/tools/","canonical":"https://djangodocs.dev/fr/3.2/topics/testing/tools/","summary":"Django propose un petit set d’outils bien pratiques lors de l’écriture de tests. Le client de test Lien vers cette rubrique # Le client de test est une classe…","html":"<h1>Outils de test<a class=\"heading-anchor\" href=\"#testing-tools\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django propose un petit set d’outils bien pratiques lors de l’écriture de tests.</p>\n<section id=\"the-test-client\">\n<span id=\"test-client\"></span><h2>Le client de test<a class=\"heading-anchor\" href=\"#the-test-client\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Le client de test est une classe Python se comportant comme un navigateur Web simpliste, permettant de tester les vues et d’interagir par programmation avec votre application Django.</p>\n<p>Voici plusieurs choses que vous pouvez faire avec le client de test :</p>\n<ul class=\"simple\">\n<li><p>Simuler des requêtes GET et POST sur une URL et examiner la réponse, que ce soit les détails HTTP de bas niveau (en-têtes de la réponse et codes d’état) ou le contenu de la page renvoyée.</p></li>\n<li><p>Voir la chaîne des redirections (le cas échéant) et contrôler l’URL et le code de statut à chaque étape.</p></li>\n<li><p>Tester qu’une requête données est rendue par un gabarit Django donné, et que le contexte du gabarit contient certaines valeurs.</p></li>\n</ul>\n<p>Notez que le client de test n’est pas conçu pour remplacer <a class=\"reference external\" href=\"https://www.selenium.dev/\">Selenium</a> ou d’autres systèmes utilisant un navigateur réel. Le client de test de Django a un objectif différent. En bref :</p>\n<ul class=\"simple\">\n<li><p>Utiliser le client de test de Django pour confirmer que le gabarit correct a été utilisé pour le rendu et que ce gabarit à reçu les bonnes données de contexte.</p></li>\n<li><p>Utilisez des systèmes basés sur de vrais navigateurs comme <a class=\"reference external\" href=\"https://www.selenium.dev/\">Selenium</a> pour tester le HTML <em>produit</em> et le <em>comportement</em> des pages Web, en particulier les fonctionnalités JavaScript. Django offre aussi une prise en charge spéciale pour ces systèmes ; consultez la section sur <a class=\"reference internal\" href=\"#django.test.LiveServerTestCase\" title=\"django.test.LiveServerTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">LiveServerTestCase</span></code></a> pour plus de détails.</p></li>\n</ul>\n<p>Une suite de tests complète devrait utiliser une combinaison de ces deux types.</p>\n<section id=\"overview-and-a-quick-example\">\n<h3>Aperçu et exemple rapide<a class=\"heading-anchor\" href=\"#overview-and-a-quick-example\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour utiliser le client de test, créez une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.test.Client</span></code> et récupérez des pages Web :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span><span class=\"s1\">&#39;/login/&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;username&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;john&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;password&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;smith&#39;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span>\n<span class=\"go\">200</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/details/&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span>\n<span class=\"go\">b&#39;&lt;!DOCTYPE html...&#39;</span>\n</code></pre></div>\n<p>Comme cet exemple le suggère, vous pouvez créer des instances de <code class=\"docutils literal notranslate\"><span class=\"pre\">Client</span></code> à partir d’une session de l’interpréteur Python interactif.</p>\n<p>Signalons quelques éléments importants au sujet du fonctionnement du client de test :</p>\n<ul>\n<li><p>Le client de test n’a <em>pas</em> besoin que le serveur Web soit lancé. En fait, il fonctionne tout à fait correctement sans aucun serveur Web actif ! Et cela parce qu’il s’adresse directement à l’infrastructure Django sans passer par la couche HTTP. Cela permet d’accélérer le fonctionnement des tests unitaires.</p></li>\n<li><p>Lors de la récupération des pages, n’oubliez pas de n’indiquer que le <em>chemin</em> de l’URL, sans mentionner tout le nom de domaine. Par exemple, ceci est correct :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/login/&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Mais pas ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;https://www.example.com/login/&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le client de test n’est pas capable de récupérer des pages Web qui ne sont pas basées sur votre projet Django. Si vous avez besoin de récupérer d’autres pages Web, utilisez un module standard de la bibliothèque Python, comme <a class=\"reference external\" href=\"https://docs.python.org/3/library/urllib.html#module-urllib\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">urllib</span></code></a>.</p>\n</li>\n<li><p>Pour résoudre des URL, le client de test utilise la configuration d’URL qui est désignée par le réglage <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a>.</p></li>\n<li><p>Même si l’exemple ci-dessus fonctionne dans un interpréteur Python interactif, certaines fonctionnalités du client de test, notamment celles liées aux gabarits, ne sont disponibles que <em>lorsque les tests sont lancés</em>.</p>\n<p>Ceci s’explique par le fait que le lanceur de tests de Django fait sa propre cuisine pour déterminer quel gabarit a été chargé pour une vue donnée. Cette « cuisine » (essentiellement un correctif en mémoire du système de gabarits de Django) n’est opérée que durant le fonctionnement des tests.</p>\n</li>\n<li><p>Par défaut, le client de test désactive tous les contrôles CSRF effectués par votre site.</p>\n<p>Si pour une raison quelconque vous * voulez* que le client de test effectue les contrôles CSRF, vous pouvez créer une instance du client de test avec les contrôles CSRF actifs. Pour cela, passez le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">enforce_csrf_checks</span></code> au moment de créer le client :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">csrf_client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">(</span><span class=\"n\">enforce_csrf_checks</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"making-requests\">\n<h3>Lancement de requêtes<a class=\"heading-anchor\" href=\"#making-requests\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La classe <code class=\"docutils literal notranslate\"><span class=\"pre\">django.test.Client</span></code> permet de simuler des requêtes HTTP.</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Client</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">enforce_csrf_checks</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">json_encoder</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">DjangoJSONEncoder</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">defaults</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Aucun paramètre n’est obligatoire au moment de la création de l’instance. Vous pouvez cependant indiquer des paramètres nommés pour définir des en-têtes par défaut. Dans l’exemple suivant, un en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">User-Agent</span></code> est envoyé avec chaque requête :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">(</span><span class=\"n\">HTTP_USER_AGENT</span><span class=\"o\">=</span><span class=\"s1\">&#39;Mozilla/5.0&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Les valeurs de paramètres nommés passés dans <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> aux méthodes <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a>, <a class=\"reference internal\" href=\"#django.test.Client.post\" title=\"django.test.Client.post\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">post()</span></code></a>, etc. ont la priorité sur les valeurs par défaut transmises au constructeur de la classe.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">enforce_csrf_checks</span></code> peut être utilisé pour tester la protection CSRF (voir au-dessus).</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">json_encoder</span></code> permet de définir un codeur JSON personnalisé pour la sérialisation JSON décrite dans <a class=\"reference internal\" href=\"#django.test.Client.post\" title=\"django.test.Client.post\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">post()</span></code></a>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">raise_request_exception</span></code> permet de contrôler si les exceptions générées pendant la requête doivent aussi être générées dans le test. Vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> par défaut.</p>\n<p>Dès que vous avez à disposition une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Client</span></code>, vous pouvez appeler au choix l’une des méthodes suivantes :</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.get\">\n<span class=\"sig-name descname\"><span class=\"pre\">get</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.get\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête GET utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>, qui est documenté plus bas.</p>\n<p>Les paires clé-valeur dans le dictionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> servent à créer les données utiles de GET. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customers/details/&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;age&#39;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>…aboutit à l’évaluation d’une requête GET équivalente à :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>/customers/details/?name=fred&amp;age=7\n</code></pre></div>\n<p>Le paramètre nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> peut être utilisé pour indiquer les en-têtes envoyés avec la requête. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customers/details/&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;age&#39;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">},</span>\n<span class=\"gp\">... </span>      <span class=\"n\">HTTP_ACCEPT</span><span class=\"o\">=</span><span class=\"s1\">&#39;application/json&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>…envoie l’en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">HTTP_ACCEPT</span></code> à la vue de détail, ce qui constitue une bonne manière de tester des chemins de code utilisant la méthode <a class=\"reference internal\" href=\"/fr/3.2/ref/request-response/#django.http.HttpRequest.accepts\" title=\"django.http.HttpRequest.accepts\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">django.http.HttpRequest.accepts()</span></code></a>.</p>\n<aside class=\"admonition-cgi-specification admonition\">\n<p class=\"admonition-title\">Spécification CGI</p>\n<p>Les en-têtes envoyés par <code class=\"docutils literal notranslate\"><span class=\"pre\">**extra</span></code> doivent respecter la spécification <a class=\"reference external\" href=\"https://www.w3.org/CGI/\">CGI</a>. Par exemple, pour émuler un en-tête « Host » différent de celui envoyé dans la requête HTTP du navigateur vers le serveur, il faut transmettre <code class=\"docutils literal notranslate\"><span class=\"pre\">HTTP_HOST</span></code>.</p>\n</aside>\n<p>Si vous disposez déjà des paramètres GET sous une forme déjà codée pour l’URL, vous pouvez utiliser cette forme au lieu du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code>. Par exemple, la requête GET précédente pourrait aussi être émise par :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customers/details/?name=fred&amp;age=7&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous fournissez à la fois une URL contenant des données GET codée et un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code>, ce dernier a la priorité.</p>\n<p>Si vous définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, le client suit d’éventuelles redirections et l’objet réponse possédera un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">redirect_chain</span></code> contenant des tuples formés des URL intermédiaires et de leur code d’état.</p>\n<p>Si vous aviez une URL <code class=\"docutils literal notranslate\"><span class=\"pre\">/redirect_me/</span></code> redirigeant vers <code class=\"docutils literal notranslate\"><span class=\"pre\">/next/</span></code>, redirigeant lui-même vers <code class=\"docutils literal notranslate\"><span class=\"pre\">/final/</span></code>, voici ce que vous obtiendriez :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/redirect_me/&#39;</span><span class=\"p\">,</span> <span class=\"n\">follow</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">redirect_chain</span>\n<span class=\"go\">[(&#39;http://testserver/next/&#39;, 302), (&#39;http://testserver/final/&#39;, 302)]</span>\n</code></pre></div>\n<p>Si vous définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, le client émule une requête HTTPS.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.post\">\n<span class=\"sig-name descname\"><span class=\"pre\">post</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">MULTIPART_CONTENT</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.post\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête POST utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>, qui est documenté plus bas.</p>\n<p>Les paires clé-valeur dans le dictionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> servent à créer les données de soumission POST. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span><span class=\"s1\">&#39;/login/&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;passwd&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;secret&#39;</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>…aboutit à l’évaluation d’une requête POST vers cette URL :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">/</span><span class=\"n\">login</span><span class=\"o\">/</span>\n</code></pre></div>\n<p>…contenant ces données POST :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"n\">fred</span><span class=\"o\">&amp;</span><span class=\"n\">passwd</span><span class=\"o\">=</span><span class=\"n\">secret</span>\n</code></pre></div>\n<p>Si vous indiquez <em class=\"mimetype\">application/json</em> dans <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code>, les données <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> sont sérialisées en utilisant <a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#json.dumps\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">json.dumps()</span></code></a> s’il s’agit d’un dict, d’une liste ou d’un tuple. La sérialisation est appliquée par défaut avec <a class=\"reference internal\" href=\"/fr/3.2/topics/serialization/#django.core.serializers.json.DjangoJSONEncoder\" title=\"django.core.serializers.json.DjangoJSONEncoder\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DjangoJSONEncoder</span></code></a>, mais cette classe peut être remplacée en fournissant le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">json_encoder</span></code> à <a class=\"reference internal\" href=\"#django.test.Client\" title=\"django.test.Client\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Client</span></code></a>. Cette sérialisation se produit également pour les requêtes <a class=\"reference internal\" href=\"#django.test.Client.put\" title=\"django.test.Client.put\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">put()</span></code></a>, <a class=\"reference internal\" href=\"#django.test.Client.patch\" title=\"django.test.Client.patch\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">patch()</span></code></a> et <a class=\"reference internal\" href=\"#django.test.Client.delete\" title=\"django.test.Client.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">delete()</span></code></a>.</p>\n<p>Si vous renseignez tout autre <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code> (par ex. <em class=\"mimetype\">text/xml</em> pour des données utiles XML), le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> est envoyé tel quel dans la requête POST, en plaçant le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code> dans l’en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Type</span></code>.</p>\n<p>Si le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code> n’est pas renseigné, les valeurs contenues dans <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> sont transmises avec un type de contenu <em class=\"mimetype\">multipart/form-data</em>. Dans ce cas, les paires clé-valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> sont codées sous forme de message composite (<code class=\"docutils literal notranslate\"><span class=\"pre\">multipart</span></code>) et servent à créer les données utiles de POST.</p>\n<p>Pour envoyer plusieurs valeurs pour un même clé, par exemple pour indiquer les sélections d’un élément <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;select</span> <span class=\"pre\">multiple&gt;</span></code>, indiquez les valeurs de la clé sous forme de liste ou de tuple. Par exemple, le contenu suivant de <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> envoie trois valeurs sélectionnées pour le champ nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">choices</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"p\">{</span><span class=\"s1\">&#39;choices&#39;</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;d&#39;</span><span class=\"p\">)}</span>\n</code></pre></div>\n<p>L’envoi de fichiers est un cas particulier. Pour envoyer un fichier par POST, il suffit d’indiquer comme clé le nom du champ de fichier et comme valeur un pointeur de fichier référençant le fichier à envoyer. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&#39;wishlist.doc&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;rb&#39;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">fp</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customers/wishes/&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;attachment&#39;</span><span class=\"p\">:</span> <span class=\"n\">fp</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>(Le nom <code class=\"docutils literal notranslate\"><span class=\"pre\">attachment</span></code> n’a ici aucune signification particulière ; utilisez le nom de champ attendu par votre code de traitement de fichier.)</p>\n<p>Il est aussi possible de fournir un objet de type fichier (par ex. <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#io.StringIO\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StringIO</span></code></a> ou <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#io.BytesIO\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BytesIO</span></code></a>) comme pointeur de fichier. Si le fichier est destiné à un champ <a class=\"reference internal\" href=\"/fr/3.2/ref/models/fields/#django.db.models.ImageField\" title=\"django.db.models.ImageField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ImageField</span></code></a>, l’objet a besoin d’un attribut  <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> passant la validation de <a class=\"reference internal\" href=\"/fr/3.2/ref/validators/#django.core.validators.validate_image_file_extension\" title=\"django.core.validators.validate_image_file_extension\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">validate_image_file_extension</span></code></a>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">io</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BytesIO</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">img</span> <span class=\"o\">=</span> <span class=\"n\">BytesIO</span><span class=\"p\">(</span><span class=\"sa\">b</span><span class=\"s1\">&#39;mybinarydata&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">img</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;myimage.jpg&#39;</span>\n</code></pre></div>\n<p>Notez que si vous souhaitez utiliser le même pointeur de fichier pour plusieurs appels à <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code>, vous devrez manuellement réinitialiser ce pointeur entre les requêtes. La façon la plus simple de le faire manuellement est de fermer le fichier après qu’il a été fourni à <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code>, comme cela est fait dans l’exemple ci-dessus.</p>\n<p>Vous devez aussi être certain que le fichier est ouvert d’une manière autorisant les données à être lues. Si votre fichier contient des données binaires telles qu’une image, cela signifie que vous devrez ouvrir le fichier en mode <code class=\"docutils literal notranslate\"><span class=\"pre\">rb</span></code> (read binary).</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> joue le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n<p>Si l’URL indiquée pour la requête POST contient des paramètres codés, ceux-ci sont placés dans les données <code class=\"docutils literal notranslate\"><span class=\"pre\">request.GET</span></code>. Par exemple, si vous effectuez la requête :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span><span class=\"s1\">&#39;/login/?visitor=true&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;passwd&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;secret&#39;</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>…la vue traitant la requête peut consulter <code class=\"docutils literal notranslate\"><span class=\"pre\">request.POST</span></code> pour obtenir les données du nom et du mot de passe, et <code class=\"docutils literal notranslate\"><span class=\"pre\">request.GET</span></code> pour savoir si l’utilisateur est un visiteur.</p>\n<p>Si vous définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, le client suit d’éventuelles redirections et l’objet réponse possédera un attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">redirect_chain</span></code> contenant des tuples formés des URL intermédiaires et de leur code d’état.</p>\n<p>Si vous définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, le client émule une requête HTTPS.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.head\">\n<span class=\"sig-name descname\"><span class=\"pre\">head</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.head\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête HEAD utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Cette méthode fonctionne comme <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>, y compris les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> à la seule exception qu’aucun corps de message n’est renvoyé.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.options\">\n<span class=\"sig-name descname\"><span class=\"pre\">options</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'application/octet-stream'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.options\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête OPTIONS utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Utile pour tester les interfaces de type « REST ».</p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> est renseigné, il est utilisé comme corps de requête et un en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Type</span></code> est défini avec le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code>.</p>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> jouent le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.put\">\n<span class=\"sig-name descname\"><span class=\"pre\">put</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'application/octet-stream'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.put\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête PUT utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Utile pour tester les interfaces de type « REST ».</p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> est renseigné, il est utilisé comme corps de requête et un en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Type</span></code> est défini avec le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code>.</p>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> jouent le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.patch\">\n<span class=\"sig-name descname\"><span class=\"pre\">patch</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'application/octet-stream'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.patch\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête PATCH utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Utile pour tester les interfaces de type « REST ».</p>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> jouent le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.delete\">\n<span class=\"sig-name descname\"><span class=\"pre\">delete</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">data</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content_type</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'application/octet-stream'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.delete\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête DELETE utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Utile pour tester les interfaces de type « REST ».</p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> est renseigné, il est utilisé comme corps de requête et un en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Type</span></code> est défini avec le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type</span></code>.</p>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> jouent le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.trace\">\n<span class=\"sig-name descname\"><span class=\"pre\">trace</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">path</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">follow</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">secure</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">extra</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.trace\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Procède à une requête TRACE utilisant le chemin <code class=\"docutils literal notranslate\"><span class=\"pre\">path</span></code> indiqué et renvoie un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Utile pour simuler les tests diagnostics.</p>\n<p>Au contraire des autres méthodes de requête, <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> n’est pas fourni comme paramètre nommé afin de respecter la <span class=\"target\" id=\"index-6\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html#section-4.3.8\"><strong>RFC 7231 Section 4.3.8</strong></a>, qui interdit aux requêtes TRACE de posséder un corps.</p>\n<p>Les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">secure</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> jouent le même rôle que pour <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.login\">\n<span class=\"sig-name descname\"><span class=\"pre\">login</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">credentials</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.login\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Si un projet utilise le <a class=\"reference internal\" href=\"/fr/3.2/topics/auth/\"><span class=\"doc\">système d’authentification</span></a> de Django et que les tests connectent des utilisateurs, il est possible d’utiliser la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">login()</span></code> du client de test pour simuler la connexion d’un utilisateur au site concerné.</p>\n<p>Après l’appel à cette méthode, le client de test contiendra tous les cookies et les données de session nécessaires pour passer les tests dans lesquels des vues comptent sur des utilisateurs connectés.</p>\n<p>Le format du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">credentials</span></code> dépend du <a class=\"reference internal\" href=\"/fr/3.2/topics/auth/customizing/#authentication-backends\"><span class=\"std std-ref\">moteur d’authentification</span></a> utilisé (configuré dans le réglage <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-AUTHENTICATION_BACKENDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTHENTICATION_BACKENDS</span></code></a>). Dans le cas du moteur d’authentification standard de Django (<code class=\"docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code>), <code class=\"docutils literal notranslate\"><span class=\"pre\">credentials</span></code> doit contenir le nom d’utilisateur et le mot de passe de l’utilisateur, fournis sous la forme de paramètres nommés :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">login</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"s1\">&#39;secret&#39;</span><span class=\"p\">)</span>\n\n<span class=\"go\"># Now you can access a view that&#39;s only available to logged-in users.</span>\n</code></pre></div>\n<p>Si un autre moteur d’authentification est utilisé, cette méthode peut nécessiter un autre format de données d’authentification. Cela dépend des paramètres nécessaires à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">authenticate()</span></code> du moteur en question.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">login()</span></code> renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si les données d’authentification ont été acceptées et que la connexion s’est terminée avec succès.</p>\n<p>Pour finir, il ne faut pas oublier de créer des comptes utilisateurs avant de pouvoir utiliser cette méthode. Comme expliqué ci-dessus, le lanceur de tests fonctionne avec une base de données de test, sans aucun utilisateur par défaut. Par conséquent, les comptes utilisateurs actifs sur un site de production ne sont pas pris en compte dans des conditions de test. Les utilisateurs doivent être créés dans le cadre de la suite de tests, soit manuellement (par l’API de modèle Django), soit par un instantané de test. N’oubliez pas non plus que pour qu’un utilisateur de test dispose d’un mot de passe, il ne suffit pas de définir directement l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">password</span></code> de l’utilisateur, mais il faut passer par la fonction <a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/auth/#django.contrib.auth.models.User.set_password\" title=\"django.contrib.auth.models.User.set_password\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">set_password()</span></code></a> pour que soit stockée une empreinte correcte de mot de passe. Il est aussi possible d’employer la méthode utilitaire <a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/auth/#django.contrib.auth.models.UserManager.create_user\" title=\"django.contrib.auth.models.UserManager.create_user\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">create_user()</span></code></a> pour créer un nouvel utilisateur ainsi qu’une empreinte de mot de passe utilisable.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.force_login\">\n<span class=\"sig-name descname\"><span class=\"pre\">force_login</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">user</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">backend</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.force_login\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Si un projet utilise le <a class=\"reference internal\" href=\"/fr/3.2/topics/auth/\"><span class=\"doc\">système d’authentification</span></a> de Django, il est possible d’utiliser la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">force_login()</span></code> pour simuler la connexion d’un utilisateur du site concerné. Il est avantageux d’utiliser cette méthode à la place de <a class=\"reference internal\" href=\"#django.test.Client.login\" title=\"django.test.Client.login\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">login()</span></code></a> lorsqu’un test a besoin d’un utilisateur connecté mais que les détails de la manière dont l’utilisateur s’est connecté importent peu.</p>\n<p>Au contraire de <code class=\"docutils literal notranslate\"><span class=\"pre\">login()</span></code>, cette méthode omet les étapes d’authentification et de vérification : les utilisateurs inactifs (<a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_active=False</span></code></a>) peuvent se connecter et il n’est pas nécessaire de fournir les informations d’authentification.</p>\n<p>L’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">backend</span></code> de l’utilisateur sera défini à la valeur du paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">backend</span></code> (qui devrait être un chemin Python pointé) ou à <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.AUTHENTICATION_BACKENDS[0]</span></code> si ce paramètre n’est pas fourni. La fonction <a class=\"reference internal\" href=\"/fr/3.2/topics/auth/default/#django.contrib.auth.authenticate\" title=\"django.contrib.auth.authenticate\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">authenticate()</span></code></a> appelée par <a class=\"reference internal\" href=\"#django.test.Client.login\" title=\"django.test.Client.login\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">login()</span></code></a> annote normalement l’utilisateur de cette manière.</p>\n<p>Cette méthode est plus rapide que <code class=\"docutils literal notranslate\"><span class=\"pre\">login()</span></code> dans la mesure où les coûteux algorithmes de hachage de mot de passe sont ignorés. Notez qu’il est aussi possible d’accélérer <code class=\"docutils literal notranslate\"><span class=\"pre\">login()</span></code> en <a class=\"reference internal\" href=\"/fr/3.2/topics/testing/overview/#speeding-up-tests-auth-hashers\"><span class=\"std std-ref\">utilisant une méthode de hachage plus faible durant les tests</span></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.logout\">\n<span class=\"sig-name descname\"><span class=\"pre\">logout</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Client.logout\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Si un projet utilise le <a class=\"reference internal\" href=\"/fr/3.2/topics/auth/\"><span class=\"doc\">système d’authentification</span></a> de Django, il est possible d’utiliser la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">logout()</span></code> du client de test pour simuler la déconnexion d’un utilisateur du site concerné.</p>\n<p>Après l’appel à cette méthode, le client de test verra toutes ses données de cookies et de session réinitialisées à leurs valeurs par défaut. Les requêtes suivantes apparaîtront comme si elles provenaient d’un utilisateur anonyme (<a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/auth/#django.contrib.auth.models.AnonymousUser\" title=\"django.contrib.auth.models.AnonymousUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AnonymousUser</span></code></a>).</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"testing-responses\">\n<h3>Test des réponses<a class=\"heading-anchor\" href=\"#testing-responses\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> renvoient les deux un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code>. Cet objet n’est <em>pas</em> le même que les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> renvoyés par les vues Django ; l’objet de réponse de test possède des données supplémentaires bien utiles pour certaines vérifications dans le code des tests.</p>\n<p>Plus précisément, un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code> possède les attributs suivants :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Response</span></span><a class=\"heading-anchor\" href=\"#django.test.Response\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.client\">\n<span class=\"sig-name descname\"><span class=\"pre\">client</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.client\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le client de test utilisé pour effectuer la requête qui a renvoyé cette réponse.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.content\">\n<span class=\"sig-name descname\"><span class=\"pre\">content</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.content\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le corps de la réponse sous forme de chaîne d’octets. Il s’agit du contenu final de la page produite par la vue, ou d’un éventuel message d’erreur.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.context\">\n<span class=\"sig-name descname\"><span class=\"pre\">context</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.context\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>L’instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> du gabarit utilisé pour effectuer le rendu de gabarit qui a produit le contenu de la réponse.</p>\n<p>Si le rendu de la page à utilisé plusieurs gabarits, <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> contient une liste d’objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> dans l’ordre de leur rendu.</p>\n<p>Quel que soit le nombre de gabarits utilisés dans le processus de rendu, vous pouvez récupérer les valeurs de contexte en utilisant l’opérateur <code class=\"docutils literal notranslate\"><span class=\"pre\">[]</span></code>. Par exemple, la variable de contexte <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> peut être récupérée ainsi :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/foo/&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;Arthur&#39;</span>\n</code></pre></div>\n<aside class=\"admonition-not-using-django-templates admonition\">\n<p class=\"admonition-title\">Vous n’utilisez pas les gabarits Django ?</p>\n<p>Cet attribut n’est présent que lorsque le moteur de gabarit est <a class=\"reference internal\" href=\"/fr/3.2/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code></a>. Si vous utilisez un autre moteur, <a class=\"reference internal\" href=\"/fr/3.2/ref/template-response/#django.template.response.SimpleTemplateResponse.context_data\" title=\"django.template.response.SimpleTemplateResponse.context_data\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">context_data</span></code></a> peut constituer une alternative viable pour les réponses possédant cet attribut.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.exc_info\">\n<span class=\"sig-name descname\"><span class=\"pre\">exc_info</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.exc_info\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un tuple de trois valeurs fournissant des informations sur l’exception non traitée, le cas échéant, qui est apparue durant la vue.</p>\n<p>Les valeurs sont (type, valeur, trace d’erreur), tout comme ce que Python renvoie dans <a class=\"reference external\" href=\"https://docs.python.org/3/library/sys.html#sys.exc_info\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sys.exc_info()</span></code></a>. Leur signification est :</p>\n<ul class=\"simple\">\n<li><p><em>type</em> : le type de l’exception.</p></li>\n<li><p><em>valeur</em> : l’instance de l’exception.</p></li>\n<li><p><em>trace d’erreur</em> : Un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Traceback</span></code> qui englobe la pile d’appels au moment où l’exception a été initialement déclenchée.</p></li>\n</ul>\n<p>Si aucune exception ne s’est produite, <code class=\"docutils literal notranslate\"><span class=\"pre\">exc_info</span></code> contient <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.json\">\n<span class=\"sig-name descname\"><span class=\"pre\">json</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.Response.json\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le corps de la réponse, analysée en JSON. Les paramètres nommés supplémentaires sont transmis à <a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#json.loads\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">json.loads()</span></code></a>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/foo/&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">json</span><span class=\"p\">()[</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;Arthur&#39;</span>\n</code></pre></div>\n<p>Si l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Type</span></code> n’est pas <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;application/json&quot;</span></code>, une erreur <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#ValueError\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValueError</span></code></a> sera signalée au moment d’analyser la réponse.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.request\">\n<span class=\"sig-name descname\"><span class=\"pre\">request</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.request\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Les données de requête à l’origine de la réponse.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.wsgi_request\">\n<span class=\"sig-name descname\"><span class=\"pre\">wsgi_request</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.wsgi_request\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>L’instance <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIRequest</span></code> générée par le gestionnaire de test qui a produit la réponse.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.status_code\">\n<span class=\"sig-name descname\"><span class=\"pre\">status_code</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.status_code\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le statut HTTP de la réponse sous forme de nombre entier. Pour une liste exhaustive des codes définis, voir le <a class=\"reference external\" href=\"https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml\">registre IANA des codes de statut</a>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.templates\">\n<span class=\"sig-name descname\"><span class=\"pre\">templates</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.templates\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Une liste d’instances de gabarits (<code class=\"docutils literal notranslate\"><span class=\"pre\">Template</span></code>) ayant servi à rendre le contenu final, dans l’ordre de leur utilisation. Pour chaque gabarit de la liste, utilisez <code class=\"docutils literal notranslate\"><span class=\"pre\">template.name</span></code> pour obtenir le nom de fichier du gabarit si celui-ci a été chargé à partir d’un fichier (le nom est une chaîne du genre <code class=\"docutils literal notranslate\"><span class=\"pre\">'admin/index.html'</span></code>).</p>\n<aside class=\"admonition-not-using-django-templates admonition\">\n<p class=\"admonition-title\">Vous n’utilisez pas les gabarits Django ?</p>\n<p>Cet attribut n’est présent que lorsque le moteur de gabarit est <a class=\"reference internal\" href=\"/fr/3.2/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code></a>. Si vous utilisez un autre moteur, <a class=\"reference internal\" href=\"/fr/3.2/ref/template-response/#django.template.response.SimpleTemplateResponse.template_name\" title=\"django.template.response.SimpleTemplateResponse.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a> peut constituer une alternative viable si vous n’avez besoin que du nom du gabarit utilisé pour le rendu.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Response.resolver_match\">\n<span class=\"sig-name descname\"><span class=\"pre\">resolver_match</span></span><a class=\"heading-anchor\" href=\"#django.test.Response.resolver_match\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Une instance de <a class=\"reference internal\" href=\"/fr/3.2/ref/urlresolvers/#django.urls.ResolverMatch\" title=\"django.urls.ResolverMatch\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ResolverMatch</span></code></a> pour la réponse. Vous pouvez utiliser l’attribut <a class=\"reference internal\" href=\"/fr/3.2/ref/urlresolvers/#django.urls.ResolverMatch.func\" title=\"django.urls.ResolverMatch.func\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">func</span></code></a>, par exemple, pour vérifier la vue qui a servi la réponse :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># my_view here is a function based view</span>\n<span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">resolver_match</span><span class=\"o\">.</span><span class=\"n\">func</span><span class=\"p\">,</span> <span class=\"n\">my_view</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># class-based views need to be compared by name, as the functions</span>\n<span class=\"c1\"># generated by as_view() won&#39;t be equal</span>\n<span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">resolver_match</span><span class=\"o\">.</span><span class=\"n\">func</span><span class=\"o\">.</span><span class=\"vm\">__name__</span><span class=\"p\">,</span> <span class=\"n\">MyView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"vm\">__name__</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si l’URL indiquée n’est pas trouvée, l’accès à cet attribut génère l’exception <a class=\"reference internal\" href=\"/fr/3.2/ref/exceptions/#django.urls.Resolver404\" title=\"django.urls.Resolver404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Resolver404</span></code></a>.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>Comme pour les réponses normales, il est aussi possible d’accéder aux en-têtes par <a class=\"reference internal\" href=\"/fr/3.2/ref/request-response/#django.http.HttpResponse.headers\" title=\"django.http.HttpResponse.headers\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">HttpResponse.headers</span></code></a>. Par exemple, vous pouvez retrouver le type de contenu d’une réponse avec <code class=\"docutils literal notranslate\"><span class=\"pre\">response.headers['Content-Type']</span></code>.</p>\n</section>\n<section id=\"exceptions\">\n<h3>Exceptions<a class=\"heading-anchor\" href=\"#exceptions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si le client de test fait appel à une vue qui génère une exception et que <code class=\"docutils literal notranslate\"><span class=\"pre\">Client.raise_request_exception</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, celle-ci est propagée dans le cas de test. Vous pouvez dès lors utiliser un bloc <code class=\"docutils literal notranslate\"><span class=\"pre\">try</span> <span class=\"pre\">...</span> <span class=\"pre\">except</span></code> standard ou <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertRaises()</span></code></a> pour tester l’exception générée.</p>\n<p>Les seules exceptions qui ne sont pas visibles pour le client de test sont <a class=\"reference internal\" href=\"/fr/3.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a>, <a class=\"reference internal\" href=\"/fr/3.2/ref/exceptions/#django.core.exceptions.PermissionDenied\" title=\"django.core.exceptions.PermissionDenied\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionDenied</span></code></a>, <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#SystemExit\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SystemExit</span></code></a> et <a class=\"reference internal\" href=\"/fr/3.2/ref/exceptions/#django.core.exceptions.SuspiciousOperation\" title=\"django.core.exceptions.SuspiciousOperation\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SuspiciousOperation</span></code></a>. Django intercepte en interne ces exceptions et les convertit en code de réponse HTTP adéquat. Dans ces situations, vous pouvez tester la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">response.status_code</span></code>.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">Client.raise_request_exception</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, le client de test renverra une erreur 500 comme le ferait un navigateur. La réponse possède l’attribut <a class=\"reference internal\" href=\"#django.test.Response.exc_info\" title=\"django.test.Response.exc_info\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">exc_info</span></code></a> pour fournir des informations sur l’exception non traitée.</p>\n</section>\n<section id=\"persistent-state\">\n<h3>État persistant<a class=\"heading-anchor\" href=\"#persistent-state\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’état du client de test est persistant. Si une réponse renvoie un cookie, celui-ci est stocké dans le client de test et il sera ensuite envoyé dans les requêtes <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> subséquentes.</p>\n<p>Les politiques d’expiration de ces cookies ne sont pas respectées. Si vous souhaitez faire expirer un cookie, supprimez-le manuellement ou créez une nouvelle instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Client</span></code> (ce qui aura comme conséquence de supprimer tous les cookies).</p>\n<p>Un client de test possède deux attributs qui stockent les informations d’état persistantes. Vous pouvez accéder à ces propriétés dans le cadre d’une condition de test.</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.cookies\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Client.</span></span><span class=\"sig-name descname\"><span class=\"pre\">cookies</span></span><a class=\"heading-anchor\" href=\"#django.test.Client.cookies\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un objet Python <a class=\"reference external\" href=\"https://docs.python.org/3/library/http.cookies.html#http.cookies.SimpleCookie\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SimpleCookie</span></code></a> contenant les valeurs actuelles de tous les cookies du client. Consultez la documentation du module <a class=\"reference external\" href=\"https://docs.python.org/3/library/http.cookies.html#module-http.cookies\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">http.cookies</span></code></a> pour en savoir plus.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.Client.session\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Client.</span></span><span class=\"sig-name descname\"><span class=\"pre\">session</span></span><a class=\"heading-anchor\" href=\"#django.test.Client.session\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un objet de type dictionnaire contenant les informations de session. Consultez la <a class=\"reference internal\" href=\"/fr/3.2/topics/http/sessions/\"><span class=\"doc\">documentation des sessions</span></a> pour plus de détails.</p>\n<p>Pour modifier la session et l’enregistrer, elle doit être d’abord stockée dans une variable (car un nouveau <code class=\"docutils literal notranslate\"><span class=\"pre\">SessionStore</span></code> est créé chaque fois qu’on accède à cette propriété) :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_something</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"n\">session</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">session</span>\n    <span class=\"n\">session</span><span class=\"p\">[</span><span class=\"s1\">&#39;somekey&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;test&#39;</span>\n    <span class=\"n\">session</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n</dd></dl>\n\n</section>\n<section id=\"setting-the-language\">\n<h3>Définition de la langue<a class=\"heading-anchor\" href=\"#setting-the-language\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lors des tests d’applications qui prennent en charge l’internationalisation et la localisation, il peut être souhaitable de définir la langue de la requête du client de test. La méthode à employer dépend de l’activation ou non de <a class=\"reference internal\" href=\"/fr/3.2/ref/middleware/#django.middleware.locale.LocaleMiddleware\" title=\"django.middleware.locale.LocaleMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">LocaleMiddleware</span></code></a>.</p>\n<p>Si l’intergiciel est activé, la langue peut être définie en créant un cookie nommé <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-LANGUAGE_COOKIE_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LANGUAGE_COOKIE_NAME</span></code></a> et une valeur contenant le code de langue :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_language_using_cookie</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">cookies</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">({</span><span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">LANGUAGE_COOKIE_NAME</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fr&#39;</span><span class=\"p\">})</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span><span class=\"p\">,</span> <span class=\"sa\">b</span><span class=\"s2\">&quot;Bienvenue sur mon site.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>ou en incluant l’en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Accept-Language</span></code> dans la requête :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_language_using_header</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">,</span> <span class=\"n\">HTTP_ACCEPT_LANGUAGE</span><span class=\"o\">=</span><span class=\"s1\">&#39;fr&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span><span class=\"p\">,</span> <span class=\"sa\">b</span><span class=\"s2\">&quot;Bienvenue sur mon site.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Voir <a class=\"reference internal\" href=\"/fr/3.2/topics/i18n/translation/#how-django-discovers-language-preference\"><span class=\"std std-ref\">Processus de découverte de la préférence de langue par Django</span></a> pour plus de détails.</p>\n<p>Si l’intergiciel n’est pas activé, la langue active peut être définie en utilisant <a class=\"reference internal\" href=\"/fr/3.2/ref/utils/#django.utils.translation.override\" title=\"django.utils.translation.override\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">translation.override()</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">translation</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_language_using_override</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">with</span> <span class=\"n\">translation</span><span class=\"o\">.</span><span class=\"n\">override</span><span class=\"p\">(</span><span class=\"s1\">&#39;fr&#39;</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">content</span><span class=\"p\">,</span> <span class=\"sa\">b</span><span class=\"s2\">&quot;Bienvenue sur mon site.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Voir <a class=\"reference internal\" href=\"/fr/3.2/topics/i18n/translation/#explicitly-setting-the-active-language\"><span class=\"std std-ref\">Définition explicite de la langue active</span></a> pour plus de détails.</p>\n</section>\n<section id=\"example\">\n<h3>Exemple<a class=\"heading-anchor\" href=\"#example\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’exemple suivant est un test unitaire exploitant le client de test :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">unittest</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SimpleTest</span><span class=\"p\">(</span><span class=\"n\">unittest</span><span class=\"o\">.</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setUp</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Every test needs a client.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_details</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Issue a GET request.</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/details/&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Check that the response is 200 OK.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Check that the rendered context contains 5 customers.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;customers&#39;</span><span class=\"p\">]),</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p><a class=\"reference internal\" href=\"/fr/3.2/topics/testing/advanced/#django.test.RequestFactory\" title=\"django.test.RequestFactory\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.test.RequestFactory</span></code></a></p>\n</aside>\n</section>\n</section>\n<section id=\"provided-test-case-classes\">\n<span id=\"django-testcase-subclasses\"></span><h2>Classes de cas de test disponibles<a class=\"heading-anchor\" href=\"#provided-test-case-classes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les classes de test unitaire normales de Python étendent la classe de base <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">unittest.TestCase</span></code></a>. Django fournit plusieurs extensions de cette classe de base :</p>\n<figure class=\"align-default\" id=\"id4\">\n<span id=\"testcase-hierarchy-diagram\"></span><a class=\"reference internal image-reference\" href=\"../../../../../../_images/django_unittest_classes_hierarchy.svg\"><img alt=\"Hierarchy of Django unit testing classes (TestCase subclasses)\" src=\"/fr/3.2/_images/django_unittest_classes_hierarchy.svg\" style=\"width: 508px; height: 328px;\" />\n</a>\n<figcaption>\n<p><span class=\"caption-text\">Hiérarchie des classes de tests unitaires de Django</span><a class=\"heading-anchor\" href=\"#id4\"><span class=\"visually-hidden\">Lien vers cette image</span><span aria-hidden=\"true\">#</span></a></p>\n</figcaption>\n</figure>\n<p>Il est possible de convertir une classe <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">unittest.TestCase</span></code></a> normale en une des sous-classes : remplacez la classe de base des tests <code class=\"docutils literal notranslate\"><span class=\"pre\">unittest.TestCase</span></code> par la sous-classe. Toutes les fonctionnalités standard de Python pour les tests unitaires sont toujours disponibles, et vous obtenez en plus quelques éléments utiles tels que documentés dans chaque section ci-dessous.</p>\n<section id=\"simpletestcase\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code><a class=\"heading-anchor\" href=\"#simpletestcase\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SimpleTestCase</span></span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Une sous-classe de <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">unittest.TestCase</span></code></a> qui ajoute cette fonctionnalité :</p>\n<ul class=\"simple\">\n<li><p>Certaines assertions utiles comme :</p>\n<ul>\n<li><p>Vérification qu’un objet exécutable <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertRaisesMessage\" title=\"django.test.SimpleTestCase.assertRaisesMessage\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">génère</span> <span class=\"pre\">une</span> <span class=\"pre\">exception</span> <span class=\"pre\">donnée</span></code></a>.</p></li>\n<li><p>Vérification qu’un objet exécutable <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertWarnsMessage\" title=\"django.test.SimpleTestCase.assertWarnsMessage\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">génère</span> <span class=\"pre\">un</span> <span class=\"pre\">avertissement</span> <span class=\"pre\">donné</span></code></a>.</p></li>\n<li><p>Le test de <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertFieldOutput\" title=\"django.test.SimpleTestCase.assertFieldOutput\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">rendu</span> <span class=\"pre\">et</span> <span class=\"pre\">de</span> <span class=\"pre\">traitement</span> <span class=\"pre\">d'erreur</span></code></a> des champs de formulaire.</p></li>\n<li><p>Le test de <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertContains\" title=\"django.test.SimpleTestCase.assertContains\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">présence</span> <span class=\"pre\">ou</span> <span class=\"pre\">d'absence</span> <span class=\"pre\">d'un</span> <span class=\"pre\">fragment</span> <span class=\"pre\">donné</span> <span class=\"pre\">dans</span> <span class=\"pre\">des</span> <span class=\"pre\">réponses</span> <span class=\"pre\">HTML</span></code></a>.</p></li>\n<li><p>La vérification qu’un gabarit <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertTemplateUsed\" title=\"django.test.SimpleTestCase.assertTemplateUsed\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">a</span> <span class=\"pre\">été</span> <span class=\"pre\">ou</span> <span class=\"pre\">n'a</span> <span class=\"pre\">pas</span> <span class=\"pre\">été</span> <span class=\"pre\">utilisé</span> <span class=\"pre\">pour</span> <span class=\"pre\">générer</span> <span class=\"pre\">un</span> <span class=\"pre\">contenu</span> <span class=\"pre\">de</span> <span class=\"pre\">réponse</span> <span class=\"pre\">donné</span></code></a>.</p></li>\n<li><p>La vérification que deux meth:URL &lt;SimpleTestCase.assertURLEqual&gt; sont égales.</p></li>\n<li><p>La vérification qu’une <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertRedirects\" title=\"django.test.SimpleTestCase.assertRedirects\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">redirection</span> <span class=\"pre\">HTTP</span></code></a> a été effectuée par une application.</p></li>\n<li><p>La comparaison robuste entre deux <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">fragments</span> <span class=\"pre\">HTML</span></code></a> ou la présence ou absence d’un <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertInHTML\" title=\"django.test.SimpleTestCase.assertInHTML\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">fragment</span> <span class=\"pre\">HTML</span> <span class=\"pre\">dans</span> <span class=\"pre\">un</span> <span class=\"pre\">autre</span></code></a>.</p></li>\n<li><p>La comparaison robuste entre deux <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertXMLEqual\" title=\"django.test.SimpleTestCase.assertXMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">fragments</span> <span class=\"pre\">XML</span></code></a>.</p></li>\n<li><p>La comparaison robuste entre deux <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertJSONEqual\" title=\"django.test.SimpleTestCase.assertJSONEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">fragments</span> <span class=\"pre\">JSON</span></code></a>.</p></li>\n</ul>\n</li>\n<li><p>La capacité de lancer des tests avec des <a class=\"reference internal\" href=\"#overriding-settings\"><span class=\"std std-ref\">réglages modifiés</span></a>.</p></li>\n<li><p>L’utilisation du <a class=\"reference internal\" href=\"#django.test.Client\" title=\"django.test.Client\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Client</span></code></a> <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.client\" title=\"django.test.SimpleTestCase.client\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">client</span></code></a>.</p></li>\n</ul>\n<p>Si les tests effectuent des requêtes de base de données, utilisez les sous-classes  <a class=\"reference internal\" href=\"#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code></a> ou <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></code></a>.</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.databases\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">databases</span></span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.databases\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><a class=\"reference internal\" href=\"#django.test.SimpleTestCase\" title=\"django.test.SimpleTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code></a> n’autorise pas de requête de base de données par défaut. Ceci permet d’éviter l’exécution de requêtes d’écriture qui pourraient affecter d’autres tests dans la mesure où chaque test d’une suite <code class=\"docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code> n’est pas lancé dans une transaction. Si ce problème ne vous concerne pas, vous pouvez désactiver ce comportement en définissant l’attribut de classe <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">'__all__'</span></code> sur la classe de test.</p>\n</dd></dl>\n\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code> et ses sous-classes (par ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code>, …) se basent sur <code class=\"docutils literal notranslate\"><span class=\"pre\">setUpClass()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">tearDownClass()</span></code> pour effectuer des initialisations liées à la classe entière (par exemple la surcharge de réglages). Si vous avez besoin de surcharger ces méthodes, n’oubliez pas d’appeler l’implémentation de <code class=\"docutils literal notranslate\"><span class=\"pre\">super</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setUpClass</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">setUpClass</span><span class=\"p\">()</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">tearDownClass</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">tearDownClass</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Prenez garde de prendre en compte le comportement Python quand une exception est générée durant <code class=\"docutils literal notranslate\"><span class=\"pre\">setUpClass()</span></code>. Quand cela se produit, aucun test de la classe n’est exécuté et <code class=\"docutils literal notranslate\"><span class=\"pre\">tearDownClass()</span></code> n’est pas non plus appelée. Dans le cas de <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.test.TestCase</span></code></a>, la transaction créée dans <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> n’est pas proprement traitée ce qui peut produire divers symptômes, y compris une faute de segmentation sur certaines plates-formes (signalé sur macOS). Si vous souhaitez provoquer intentionnellement une exception telle que <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.SkipTest\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">unittest.SkipTest</span></code></a> dans <code class=\"docutils literal notranslate\"><span class=\"pre\">setUpClass()</span></code>, faites-le avant d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> pour éviter ces problèmes.</p>\n</aside>\n<aside class=\"version-note version-changed\" data-version=\"3.1\">\n<p class=\"version-note-title\">Changed in Django 3.1</p><p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">debug()</span></code> a été implémentée pour permettre de lancer un test sans collecter le résultat et intercepter les exceptions.</p>\n</aside>\n</section>\n<section id=\"transactiontestcase\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code><a class=\"heading-anchor\" href=\"#transactiontestcase\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.TransactionTestCase\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">TransactionTestCase</span></span><a class=\"heading-anchor\" href=\"#django.test.TransactionTestCase\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code> hérite de <a class=\"reference internal\" href=\"#django.test.SimpleTestCase\" title=\"django.test.SimpleTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code></a> et y ajoute quelques fonctionnalités spécifiques aux bases de données :</p>\n<ul class=\"simple\">\n<li><p>Réinitialisation de la base de données à un état connu au commencement de chaque test pour faciliter les tests et l’utilisation de l’ORM.</p></li>\n<li><p>Les instantanés (<a class=\"reference internal\" href=\"#django.test.TransactionTestCase.fixtures\" title=\"django.test.TransactionTestCase.fixtures\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">fixtures</span></code></a>) de base de données.</p></li>\n<li><p>Omission de tests <a class=\"reference internal\" href=\"#skipping-tests\"><span class=\"std std-ref\">en fonction de fonctionnalités du moteur de base de données</span></a>.</p></li>\n<li><p>Les méthodes spécialisées restantes du type <a class=\"reference internal\" href=\"#django.test.TransactionTestCase.assertQuerysetEqual\" title=\"django.test.TransactionTestCase.assertQuerysetEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assert*</span></code></a>.</p></li>\n</ul>\n<p>La classe <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></code></a> de Django est une sous-classe plus couramment utilisée de <code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code> qui emploie les utilitaires de transaction de base de données pour accélérer le processus de réinitialisation de la base de données à un état connu au début de chaque test. Cependant, une des conséquences de ceci est que certains comportements de base de données ne peuvent pas être testés avec une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> de Django. Par exemple, vous ne pouvez pas tester qu’un bloc de code s’exécute dans une transaction, comme c’est exigé par l’utilisation de <a class=\"reference internal\" href=\"/fr/3.2/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update\" title=\"django.db.models.query.QuerySet.select_for_update\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">select_for_update()</span></code></a>. Dans de tels cas, il vous faut utiliser la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> sont identiques à l’exception de la manière dont la base de données est réinitialisée à un état connu et de la capacité de tester les effets de « commit » et de « rollback » dans le code :</p>\n<ul class=\"simple\">\n<li><p>La classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code> réinitialise la base de données après le lancement des tests en tronquant toutes les tables. Le code de ces tests peut valider et annuler des transactions et observer les effets de ces appels sur la base de données.</p></li>\n<li><p>D’un autre côté, un <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> ne tronque pas les tables après un test. Il enveloppe plutôt le code de test dans une transaction de base de données qui est ensuite annulée lorsque le test est terminé. Cela permet de garantir que l’annulation (« rollback ») à la fin des tests restaure la base de données à son état initial.</p></li>\n</ul>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Les tests <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> s’exécutant avec une base de données ne prenant pas en charge l’annulation (« rollback »), par exemple MySQL avec le moteur MyISAM, ainsi que toutes les instances de tests <code class=\"docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code> annulent la transaction à la fin du test en supprimant toutes les données de la base de données de test.</p>\n<p>Les applications <a class=\"reference internal\" href=\"/fr/3.2/topics/testing/overview/#test-case-serialized-rollback\"><span class=\"std std-ref\">ne verront pas leurs données rechargées</span></a>. Si vous avez besoin de cette fonctionnalité (typiquement dans le cas des applications tierces), vous pouvez définir <code class=\"docutils literal notranslate\"><span class=\"pre\">serialized_rollback</span> <span class=\"pre\">=</span> <span class=\"pre\">True</span></code> dans le corps de la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code>.</p>\n</aside>\n</section>\n<section id=\"testcase\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code><a class=\"heading-anchor\" href=\"#testcase\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.TestCase\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">TestCase</span></span><a class=\"heading-anchor\" href=\"#django.test.TestCase\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Il s’agit de la classe la plus courante pour l’écriture de tests dans Django. Elle hérite de <a class=\"reference internal\" href=\"#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code></a> (et par extension de <a class=\"reference internal\" href=\"#django.test.SimpleTestCase\" title=\"django.test.SimpleTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code></a>). Si votre application Django n’utilise pas de base de données, utilisez <a class=\"reference internal\" href=\"#django.test.SimpleTestCase\" title=\"django.test.SimpleTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SimpleTestCase</span></code></a>.</p>\n<p>La classe :</p>\n<ul class=\"simple\">\n<li><p>Enveloppe les tests dans deux blocs <a class=\"reference internal\" href=\"/fr/3.2/topics/db/transactions/#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">atomic()</span></code></a> imbriqués : un pour la classe entière et un pour chaque test. Ainsi, si vous souhaitez tester un comportement transactionnel précis de la base de données, utilisez <a class=\"reference internal\" href=\"#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code></a>.</p></li>\n<li><p>Vérifie les contraintes de base de données différées à la fin de chaque test.</p></li>\n</ul>\n<p>Elle fournit également une méthode supplémentaire :</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.TestCase.setUpTestData\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">TestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">setUpTestData</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.TestCase.setUpTestData\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le bloc <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> au niveau de la classe mentionné ci-dessus permet la création de données initiales au niveau de la classe, une seule fois pour l’ensemble de <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code>. Cette technique permet d’accélérer les tests en comparaison du travail équivalent effectué au niveau de <code class=\"docutils literal notranslate\"><span class=\"pre\">setUp()</span></code>.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setUpTestData</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Set up data for the whole TestCase</span>\n        <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">foo</span> <span class=\"o\">=</span> <span class=\"n\">Foo</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">bar</span><span class=\"o\">=</span><span class=\"s2\">&quot;Test&quot;</span><span class=\"p\">)</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test1</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Some test using self.foo</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test2</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Some other test using self.foo</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>Notez que si les tests sont exécutés pour une base de données sans prise en charge des transactions (par exemple MySQL avec le moteur MyISAM), <code class=\"docutils literal notranslate\"><span class=\"pre\">setUpTestData()</span></code> sera appelée avant chaque test, ce qui annulera le bénéfice en terme de vitesse.</p>\n<aside class=\"version-note version-changed\" data-version=\"3.2\">\n<p class=\"version-note-title\">Changed in Django 3.2</p><p>Les objets attribués aux attributs de classe dans <code class=\"docutils literal notranslate\"><span class=\"pre\">setUpTestData()</span></code> doivent prendre en charge la copie profonde avec <a class=\"reference external\" href=\"https://docs.python.org/3/library/copy.html#copy.deepcopy\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">copy.deepcopy()</span></code></a> afin de pouvoir être isolés de changements effectués par les méthodes de test. Dans les anciennes versions de Django, ces objets étaient réutilisés et leurs modifications persistaient d’une méthode de test à l’autre.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.TestCase.captureOnCommitCallbacks\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">TestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">captureOnCommitCallbacks</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">using</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">DEFAULT_DB_ALIAS</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">execute</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.TestCase.captureOnCommitCallbacks\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><aside class=\"version-note version-added\" data-version=\"3.2\">\n<p class=\"version-note-title\">New in Django 3.2</p></aside>\n<p>Renvoie un gestionnaire de contexte capturant les fonctions de rappel <a class=\"reference internal\" href=\"/fr/3.2/topics/db/transactions/#django.db.transaction.on_commit\" title=\"django.db.transaction.on_commit\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">transaction.on_commit()</span></code></a> pour la connexion de base de données indiquée. À la sortie du contexte, il renvoie une liste contenant les fonctions de rappel capturées. À partir de cette liste, vous pouvez placer des assertions sur ces fonctions ou les appeler pour produire leurs effets de bord, simulant un commit.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> est l’alias de la connexion de base de données pour laquelle les fonctions de rappel seront capturées.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">execute</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, toutes les fonctions de rappel seront exécutées au moment de la sortie du gestionnaire de contexte, dans le cas ou aucune exception n’a été produite. Ceci simule un commit après le bloc de code enveloppé.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">mail</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ContactTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">captureOnCommitCallbacks</span><span class=\"p\">(</span><span class=\"n\">execute</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">callbacks</span><span class=\"p\">:</span>\n            <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span>\n                <span class=\"s1\">&#39;/contact/&#39;</span><span class=\"p\">,</span>\n                <span class=\"p\">{</span><span class=\"s1\">&#39;message&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;I like your site&#39;</span><span class=\"p\">},</span>\n            <span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">callbacks</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">subject</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Contact Form&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">body</span><span class=\"p\">,</span> <span class=\"s1\">&#39;I like your site&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n</section>\n<section id=\"liveservertestcase\">\n<span id=\"live-test-server\"></span><h3><code class=\"docutils literal notranslate\"><span class=\"pre\">LiveServerTestCase</span></code><a class=\"heading-anchor\" href=\"#liveservertestcase\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.test.LiveServerTestCase\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">LiveServerTestCase</span></span><a class=\"heading-anchor\" href=\"#django.test.LiveServerTestCase\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">LiveServerTestCase</span></code> est à la base identique à <a class=\"reference internal\" href=\"#django.test.TransactionTestCase\" title=\"django.test.TransactionTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TransactionTestCase</span></code></a> avec une fonction supplémentaire : elle lance un serveur Django en arrière-plan lors de la préparation (« setUp ») des tests et l’arrête lors du nettoyage (« tearDown »). Cela permet l’utilisation de clients de tests automatisés autres que le <a class=\"reference internal\" href=\"#test-client\"><span class=\"std std-ref\">client élémentaire de Django</span></a>, comme par exemple le client <a class=\"reference external\" href=\"https://www.selenium.dev/\">Selenium</a>, afin d’exécuter une série de tests fonctionnels dans un navigateur et de simuler ainsi des actions d’un utilisateur réel.</p>\n<p>Le serveur « live » écoute sur <code class=\"docutils literal notranslate\"><span class=\"pre\">localhost</span></code> et se lie au port 0, ce qui utilise un port libre attribué par le système d’exploitation. L’URL du serveur est accessible dans <code class=\"docutils literal notranslate\"><span class=\"pre\">self.live_server_url</span></code> pendant les tests.</p>\n<p>Pour démontrer comment utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">LiveServerTestCase</span></code>, écrivons un test Selenium. Premièrement, il s’agit d’installer le <a class=\"reference external\" href=\"https://pypi.org/project/selenium/\">paquet selenium</a> dans le chemin Python :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>selenium\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install selenium\n</code></pre></div></div></div>\n<p>Puis, ajoutez un test basé sur <code class=\"docutils literal notranslate\"><span class=\"pre\">LiveServerTestCase</span></code> au module tests de votre application (par exemple <code class=\"docutils literal notranslate\"><span class=\"pre\">myapp/tests.py</span></code>). Pour cet exemple, nous supposons que vous utilisez l’application <a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/staticfiles/#module-django.contrib.staticfiles\" title=\"django.contrib.staticfiles: An app for handling static files.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">staticfiles</span></code></a> et que vous souhaitez disposez des fichiers statiques servis durant l’exécution des tests tout comme ce qu’on a en développement avec <code class=\"docutils literal notranslate\"><span class=\"pre\">DEBUG=True</span></code>, c’est-à-dire sans devoir les collecter avec <a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/staticfiles/#django-admin-collectstatic\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">collectstatic</span></code></a>. Nous allons utiliser la sous-classe <a class=\"reference internal\" href=\"/fr/3.2/ref/contrib/staticfiles/#django.contrib.staticfiles.testing.StaticLiveServerTestCase\" title=\"django.contrib.staticfiles.testing.StaticLiveServerTestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StaticLiveServerTestCase</span></code></a> qui fournit cette fonctionnalité. Remplacez-la par <code class=\"docutils literal notranslate\"><span class=\"pre\">django.test.LiveServerTestCase</span></code> si vous n’en avez pas besoin.</p>\n<p>Le code de ce test pourrait ressembler à ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.staticfiles.testing</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">StaticLiveServerTestCase</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">selenium.webdriver.firefox.webdriver</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">WebDriver</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MySeleniumTests</span><span class=\"p\">(</span><span class=\"n\">StaticLiveServerTestCase</span><span class=\"p\">):</span>\n    <span class=\"n\">fixtures</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;user-data.json&#39;</span><span class=\"p\">]</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setUpClass</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">setUpClass</span><span class=\"p\">()</span>\n        <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">selenium</span> <span class=\"o\">=</span> <span class=\"n\">WebDriver</span><span class=\"p\">()</span>\n        <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">implicitly_wait</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">tearDownClass</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">quit</span><span class=\"p\">()</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">tearDownClass</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_login</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"si\">%s%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">live_server_url</span><span class=\"p\">,</span> <span class=\"s1\">&#39;/login/&#39;</span><span class=\"p\">))</span>\n        <span class=\"n\">username_input</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">find_element_by_name</span><span class=\"p\">(</span><span class=\"s2\">&quot;username&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">username_input</span><span class=\"o\">.</span><span class=\"n\">send_keys</span><span class=\"p\">(</span><span class=\"s1\">&#39;myuser&#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">password_input</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">find_element_by_name</span><span class=\"p\">(</span><span class=\"s2\">&quot;password&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">password_input</span><span class=\"o\">.</span><span class=\"n\">send_keys</span><span class=\"p\">(</span><span class=\"s1\">&#39;secret&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">find_element_by_xpath</span><span class=\"p\">(</span><span class=\"s1\">&#39;//input[@value=&quot;Log in&quot;]&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">click</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Finalement, lancez le test comme ceci :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-1-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./manage.py<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>myapp.tests.MySeleniumTests.test_login\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-1-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> manage.py test myapp.tests.MySeleniumTests.test_login\n</code></pre></div></div></div>\n<p>Cet exemple ouvre Firefox automatiquement puis se rend à la page de connexion, saisit les données d’authentification et appuie sur le bouton « Log in ». Selenium propose d’autres pilotes dans le cas où Firefox n’est pas installé ou que vous voudriez tester avec un autre navigateur. L’exemple ci-dessus n’est qu’une fraction de ce que le client Selenium est capable de faire ; consultez la <a class=\"reference external\" href=\"https://selenium-python.readthedocs.io/api.html\">référence complète</a> pour plus de détails.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Lorsque les tests utilisent une base de données SQLite en mémoire, une même connexion de base de données sera partagée par deux fils d’exécution en parallèle : le fil dans lequel tourne le serveur « live » et le fil utilisé pour faire fonctionner le cas de test. Il est important de prévenir les requêtes de base de données simultanées au travers de cette connexion partagée, car cela pourrait provoquer l’échec aléatoire de certains tests. Vous devez donc vous assurer que les deux fils d’exécution n’accèdent pas à la base de données au même moment. En particulier, cela signifie que dans certains cas (par exemple juste après avoir cliqué sur un lien ou soumis un formulaire), il est nécessaire de contrôler qu’une réponse a été reçue par Selenium et que la page suivante a été chargée avant de continuer avec la suite de l’exécution des tests. Cela peur par exemple se faire en faisant attendre Selenium jusqu’à ce que la balise HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;body&gt;</span></code> soit présente dans la réponse (nécessite Selenium &gt; 2.13) :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_login</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">selenium.webdriver.support.wait</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">WebDriverWait</span>\n    <span class=\"n\">timeout</span> <span class=\"o\">=</span> <span class=\"mi\">2</span>\n    <span class=\"o\">...</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"o\">.</span><span class=\"n\">find_element_by_xpath</span><span class=\"p\">(</span><span class=\"s1\">&#39;//input[@value=&quot;Log in&quot;]&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">click</span><span class=\"p\">()</span>\n    <span class=\"c1\"># Wait until the response is received</span>\n    <span class=\"n\">WebDriverWait</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">selenium</span><span class=\"p\">,</span> <span class=\"n\">timeout</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">until</span><span class=\"p\">(</span>\n        <span class=\"k\">lambda</span> <span class=\"n\">driver</span><span class=\"p\">:</span> <span class=\"n\">driver</span><span class=\"o\">.</span><span class=\"n\">find_element_by_tag_name</span><span class=\"p\">(</span><span class=\"s1\">&#39;body&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>L’élément délicat ici est que le concept de « chargement de page » n’existe pas, particulièrement dans les applications Web modernes qui produisent du code HTML dynamique après la génération du document initial par le serveur. Ceci fait que le contrôle de la présence de <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;body&gt;</span></code> dans la réponse n’est pas forcément approprié dans tous les cas de figure. Consultez la <a class=\"reference external\" href=\"https://www.selenium.dev/documentation/webdriver/waits/#explicit-wait\">FAQ Selenium</a> ainsi que la <a class=\"reference external\" href=\"https://web.archive.org/web/20160129132110/http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_WebDriver_fails_to_find_elements_/_Does_not_block_on_page_loa\">documentation Selenium</a> pour obtenir davantage d’informations.</p>\n</aside>\n</section>\n</section>\n<section id=\"test-cases-features\">\n<h2>Fonctionnalités des cas de test<a class=\"heading-anchor\" href=\"#test-cases-features\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"default-test-client\">\n<h3>Client de test par défaut<a class=\"heading-anchor\" href=\"#default-test-client\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.client\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">client</span></span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.client\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Chaque cas de test dans une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.test.*TestCase</span></code> peut accéder à une instance du client de test de Django. Ce client est disponible dans self.client. Il est recréé pour chaque test, il n’y a donc pas besoin de se soucier de son état (comme les cookies) qui pourrait se propager d’un test à l’autre.</p>\n<p>Cela signifie qu’au lieu de créer une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Client</span></code> dans chaque test :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">unittest</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SimpleTest</span><span class=\"p\">(</span><span class=\"n\">unittest</span><span class=\"o\">.</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_details</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/details/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_index</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">()</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/index/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>…vous pouvez faire appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">self.client</span></code>, comme ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SimpleTest</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_details</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/details/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_index</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/customer/index/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"customizing-the-test-client\">\n<h3>Personnalisation du client de test<a class=\"heading-anchor\" href=\"#customizing-the-test-client\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.client_class\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">client_class</span></span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.client_class\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Si vous souhaitez utiliser une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Client</span></code> différente (par exemple une sous-classe avec un comportement adapté), utilisez l’attribut de classe <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.client_class\" title=\"django.test.SimpleTestCase.client_class\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">client_class</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span><span class=\"p\">,</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTestClient</span><span class=\"p\">(</span><span class=\"n\">Client</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Specialized methods for your environment</span>\n    <span class=\"o\">...</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTest</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"n\">client_class</span> <span class=\"o\">=</span> <span class=\"n\">MyTestClient</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_my_stuff</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Here self.client is an instance of MyTestClient...</span>\n        <span class=\"n\">call_some_test_code</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"fixture-loading\">\n<span id=\"topics-testing-fixtures\"></span><h3>Chargement des instantanés<a class=\"heading-anchor\" href=\"#fixture-loading\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.TransactionTestCase.fixtures\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">TransactionTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">fixtures</span></span><a class=\"heading-anchor\" href=\"#django.test.TransactionTestCase.fixtures\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un cas de test pour un site Web adossé à une base de données n’est pas très utile s’il n’y a pas de données en base de données. Les tests sont plus lisibles et la maintenabilité est meilleure si les objets sont créés avec l’ORM, par exemple dans <a class=\"reference internal\" href=\"#django.test.TestCase.setUpTestData\" title=\"django.test.TestCase.setUpTestData\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">TestCase.setUpTestData()</span></code></a>. Cependant, vous pouvez aussi utiliser des instantanés.</p>\n<p>Un instantané est une série de données que Django sait importer dans la base de données. Par exemple, si votre site contient des comptes utilisateurs, il peut être utile de créer un instantané de comptes utilisateurs afin de remplir la base de données pendant les tests.</p>\n<p>La façon la plus directe de créer un instantané est d’utiliser la commande <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">manage.py</span> <span class=\"pre\">dumpdata</span></code></a>, en partant du principe que le base de données contient déjà les données nécessaires. Consultez la <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">documentation</span> <span class=\"pre\">de</span> <span class=\"pre\">dumpdata</span></code></a> pour plus de détails.</p>\n<p>Après avoir créé un instantané et l’avoir placé dans un répertoire <code class=\"docutils literal notranslate\"><span class=\"pre\">fixtures</span></code> dans l’une des applications de <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>, vous pouvez l’utiliser dans vos tests unitaires en définissant un attribut de classe <code class=\"docutils literal notranslate\"><span class=\"pre\">fixtures</span></code> dans votre sous-classe de <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.test.TestCase</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Animal</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AnimalTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"n\">fixtures</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&#39;mammals.json&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;birds&#39;</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setUp</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Test definitions as before.</span>\n        <span class=\"n\">call_setup_methods</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_fluffy_animals</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># A test that uses the fixtures.</span>\n        <span class=\"n\">call_some_test_code</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Voici ce qui se passe en pratique :</p>\n<ul class=\"simple\">\n<li><p>Au début de chaque test, avant l’exécution de <code class=\"docutils literal notranslate\"><span class=\"pre\">setUp()</span></code>, Django réinitialise la base de données telle qu’elle se trouvait juste après avoir exécuté <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>.</p></li>\n<li><p>Puis, tous les instantanés nommés sont installés. Dans cet exemple, Django installe tout instantané JSON nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">mammals</span></code>, suivi par tout instantané nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">birds</span></code>. Consultez la documentation de <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#django-admin-loaddata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">loaddata</span></code></a> pour plus de détails sur la définition et l’installation d’instantanés.</p></li>\n</ul>\n<p>Pour des raisons de performance, <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></code></a> charge les instantanés une seule fois pour toute la classe de tests, avant <a class=\"reference internal\" href=\"#django.test.TestCase.setUpTestData\" title=\"django.test.TestCase.setUpTestData\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">setUpTestData()</span></code></a>, au lieu de le faire avant chaque test. Elle utilise les transactions pour réinitialiser la base de données avant chaque test. Dans tous les cas, vous pouvez être sûr que le résultat d’un test ne sera pas affecté par un autre test ou par l’ordre d’exécution des tests.</p>\n<p>Par défaut, les instantanés ne sont chargés que dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>. Si vous utilisez plusieurs bases de données et que vous définissez :<a class=\"reference internal\" href=\"#django.test.TransactionTestCase.databases\" title=\"django.test.TransactionTestCase.databases\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">TransactionTestCase.databases</span></code></a>, les instantanés seront chargés dans toutes les bases de données indiquées.</p>\n</section>\n<section id=\"urlconf-configuration\">\n<h3>Configuration des URL<a class=\"heading-anchor\" href=\"#urlconf-configuration\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si une application contient des vues, il peut être souhaitable d’inclure des tests où le client de test éprouve ces vues. Cependant, un utilisateur de l’application est libre de déployer les vues d’une application à l’URL de son choix. Cela signifie que les tests ne peuvent pas compter sur des URL figées pour accéder aux vues. Décorez vos classes ou méthodes de test avec <code class=\"docutils literal notranslate\"><span class=\"pre\">&#64;override_settings(ROOT_URLCONF=...)</span></code> pour imposer des configurations d’URL.</p>\n</section>\n<section id=\"multi-database-support\">\n<span id=\"testing-multi-db\"></span><h3>Prise en charge de plusieurs bases de données<a class=\"heading-anchor\" href=\"#multi-database-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.TransactionTestCase.databases\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">TransactionTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">databases</span></span><a class=\"heading-anchor\" href=\"#django.test.TransactionTestCase.databases\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Django met en place une base de données de test pour chaque base de données définie dans la définition de <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASES</span></code></a> dans vos réglages et qui est référencée par au moins un test au travers de <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code>.</p>\n<p>Cependant, une bonne partie du temps nécessaire à exécuter un cas de test Django est passé dans l’appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">flush</span></code> (réinitialisation des données) permettant de retrouver une base de données propre au début de chaque test. Pour un projet avec plusieurs bases de données, plusieurs commandes <code class=\"docutils literal notranslate\"><span class=\"pre\">flush</span></code> sont nécessaires (une par base de données), ce qui peut représenter un temps non négligeable, particulièrement si les tests n’ont pas pour but de tester l’activité entre plusieurs bases de données.</p>\n<p>Dans une optique d’optimisation, Django ne réinitialise que la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> au début de chaque test. Si votre configuration contient plusieurs bases de données et que certains tests nécessitent que toutes les bases de données soient propres, vous pouvez définir l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> de la suite de tests pour provoquer la réinitialisation des bases de données supplémentaires.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">TestMyViews</span><span class=\"p\">(</span><span class=\"n\">TransactionTestCase</span><span class=\"p\">):</span>\n    <span class=\"n\">databases</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;default&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;other&#39;</span><span class=\"p\">}</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_index_page_view</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">call_some_test_code</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Ce cas de test réinitialise les bases de données de test <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">other</span></code> avant d’exécuter <code class=\"docutils literal notranslate\"><span class=\"pre\">test_index_page_view</span></code>. Vous pouvez aussi indiquer <code class=\"docutils literal notranslate\"><span class=\"pre\">'__all__'</span></code> qui demande à ce que toutes les bases de données de test soient réinitialisées.</p>\n<p>L’option <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> contrôle également les bases données dans lesquelles sont chargés les instantanés (<a class=\"reference internal\" href=\"#django.test.TransactionTestCase.fixtures\" title=\"django.test.TransactionTestCase.fixtures\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">TransactionTestCase.fixtures</span></code></a>). Par défaut, les instantanés ne sont chargés que dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>.</p>\n<p>Les requêtes ciblant des bases de données absentes de <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> produiront des erreurs d’assertion pour éviter des fuites d’état entre les tests.</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.test.TestCase.databases\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">TestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">databases</span></span><a class=\"heading-anchor\" href=\"#django.test.TestCase.databases\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Par défaut, seule la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> est enveloppée dans une transaction durant l’exécution d’un cas de test ; toute tentative d’interroger une autre base de données produira une erreur d’assertion pour empêcher toute fuite d’état entre les tests.</p>\n<p>Utilisez l’attribut de classe <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> sur la classe de test pour demander l’emploi des transactions pour les bases de données autres que <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>.</p>\n<p>Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">OtherDBTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"n\">databases</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;other&#39;</span><span class=\"p\">}</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_other_db_query</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>Ce test n’autorisera que les requêtes vers las base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">other</span></code>. Comme pour <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.databases\" title=\"django.test.SimpleTestCase.databases\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">SimpleTestCase.databases</span></code></a> et <a class=\"reference internal\" href=\"#django.test.TransactionTestCase.databases\" title=\"django.test.TransactionTestCase.databases\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">TransactionTestCase.databases</span></code></a>, la constante <code class=\"docutils literal notranslate\"><span class=\"pre\">'__all__'</span></code> peut être employée pour indiquer que le test doit autoriser les requêtes vers toutes les bases de données.</p>\n</section>\n<section id=\"overriding-settings\">\n<span id=\"id1\"></span><h3>Surcharge des réglages<a class=\"heading-anchor\" href=\"#overriding-settings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Utilisez les fonctions ci-dessous pour modifier temporairement la valeur de certains réglages pendant les tests. Ne manipulez pas directement <code class=\"docutils literal notranslate\"><span class=\"pre\">django.conf.settings</span></code> car Django ne s’occupe pas de restaurer les valeurs d’origine après de telles manipulations.</p>\n</aside>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.settings\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">settings</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.settings\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>À des fins de tests, il est souvent utile de modifier temporairement un réglage puis de retrouver la valeur d’origine après l’exécution du code des tests. Pour cette situation, Django offre un gestionnaire de contexte de style Python (voir <span class=\"target\" id=\"index-7\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0343/\"><strong>PEP 343</strong></a>) nommé <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.settings\" title=\"django.test.SimpleTestCase.settings\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">settings()</span></code></a> qui peut être utilisé comme ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LoginTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_login</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n\n        <span class=\"c1\"># First check for the default behavior</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/sekrit/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRedirects</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"s1\">&#39;/accounts/login/?next=/sekrit/&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Then override the LOGIN_URL setting</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">settings</span><span class=\"p\">(</span><span class=\"n\">LOGIN_URL</span><span class=\"o\">=</span><span class=\"s1\">&#39;/other/login/&#39;</span><span class=\"p\">):</span>\n            <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/sekrit/&#39;</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRedirects</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"s1\">&#39;/other/login/?next=/sekrit/&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cet exemple surcharge le réglage <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-LOGIN_URL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">LOGIN_URL</span></code></a> pour le code contenu dans le bloc <code class=\"docutils literal notranslate\"><span class=\"pre\">with</span></code> et réapplique la valeur originale à la fin du bloc.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.modify_settings\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">modify_settings</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.modify_settings\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>La redéfinition de réglages contenant une liste de valeurs peut se révéler ardue. En pratique, l’ajout ou la suppression de valeurs est souvent suffisante. Django fournit le gestionnaire de contexte <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.modify_settings\" title=\"django.test.SimpleTestCase.modify_settings\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">modify_settings()</span></code></a> pour changer plus facilement les réglages :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MiddlewareTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_cache_middleware</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">modify_settings</span><span class=\"p\">(</span><span class=\"n\">MIDDLEWARE</span><span class=\"o\">=</span><span class=\"p\">{</span>\n            <span class=\"s1\">&#39;append&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.FetchFromCacheMiddleware&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;prepend&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.UpdateCacheMiddleware&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;remove&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"s1\">&#39;django.contrib.sessions.middleware.SessionMiddleware&#39;</span><span class=\"p\">,</span>\n                <span class=\"s1\">&#39;django.contrib.auth.middleware.AuthenticationMiddleware&#39;</span><span class=\"p\">,</span>\n                <span class=\"s1\">&#39;django.contrib.messages.middleware.MessageMiddleware&#39;</span><span class=\"p\">,</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">}):</span>\n            <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">)</span>\n            <span class=\"c1\"># ...</span>\n</code></pre></div>\n<p>Pour chaque action, vous pouvez indiquer soit une liste de valeurs, soit une chaîne. Lorsque la valeur existe déjà dans la liste, <code class=\"docutils literal notranslate\"><span class=\"pre\">append</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">prepend</span></code> n’ont pas d’effet ; de même que <code class=\"docutils literal notranslate\"><span class=\"pre\">remove</span></code> lorsque la valeur n’existe pas.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.test.override_settings\">\n<span class=\"sig-name descname\"><span class=\"pre\">override_settings</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.override_settings\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Dans le cas où vous souhaitez remplacer un réglage pour une méthode de test, Django met à disposition le décorateur <a class=\"reference internal\" href=\"#django.test.override_settings\" title=\"django.test.override_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">override_settings()</span></code></a> (voir <span class=\"target\" id=\"index-8\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0318/\"><strong>PEP 318</strong></a>). Voici comment l’utiliser :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span><span class=\"p\">,</span> <span class=\"n\">override_settings</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LoginTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@override_settings</span><span class=\"p\">(</span><span class=\"n\">LOGIN_URL</span><span class=\"o\">=</span><span class=\"s1\">&#39;/other/login/&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_login</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/sekrit/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRedirects</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"s1\">&#39;/other/login/?next=/sekrit/&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le décorateur peut aussi être appliqué à des classes <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span><span class=\"p\">,</span> <span class=\"n\">override_settings</span>\n\n<span class=\"nd\">@override_settings</span><span class=\"p\">(</span><span class=\"n\">LOGIN_URL</span><span class=\"o\">=</span><span class=\"s1\">&#39;/other/login/&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LoginTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_login</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/sekrit/&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRedirects</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">,</span> <span class=\"s1\">&#39;/other/login/?next=/sekrit/&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.test.modify_settings\">\n<span class=\"sig-name descname\"><span class=\"pre\">modify_settings</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.modify_settings\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Dans le même ordre d’idée, Django fournit le décorateur <a class=\"reference internal\" href=\"#django.test.modify_settings\" title=\"django.test.modify_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">modify_settings()</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span><span class=\"p\">,</span> <span class=\"n\">modify_settings</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MiddlewareTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@modify_settings</span><span class=\"p\">(</span><span class=\"n\">MIDDLEWARE</span><span class=\"o\">=</span><span class=\"p\">{</span>\n        <span class=\"s1\">&#39;append&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.FetchFromCacheMiddleware&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;prepend&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.UpdateCacheMiddleware&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">})</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_cache_middleware</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">)</span>\n        <span class=\"c1\"># ...</span>\n</code></pre></div>\n<p>Le décorateur peut aussi être appliqué à des classes de cas de test :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span><span class=\"p\">,</span> <span class=\"n\">modify_settings</span>\n\n<span class=\"nd\">@modify_settings</span><span class=\"p\">(</span><span class=\"n\">MIDDLEWARE</span><span class=\"o\">=</span><span class=\"p\">{</span>\n    <span class=\"s1\">&#39;append&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.FetchFromCacheMiddleware&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;prepend&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.middleware.cache.UpdateCacheMiddleware&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">})</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MiddlewareTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_cache_middleware</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/&#39;</span><span class=\"p\">)</span>\n        <span class=\"c1\"># ...</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Lorsqu’ils reçoivent une classe, ces décorateurs modifient directement la classe et la renvoie ; la classe renvoyée n’est pas une copie. Ainsi si vous essayez de manipuler les exemples ci-dessus pour que la valeur renvoyée soit nommée différemment que <code class=\"docutils literal notranslate\"><span class=\"pre\">LoginTestCase</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">MiddlewareTestCase</span></code>, vous pourriez être surpris de constater que les classes de cas de test originales sont tout de même affectées par le décorateur. Pour une classe donnée, <a class=\"reference internal\" href=\"#django.test.modify_settings\" title=\"django.test.modify_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">modify_settings()</span></code></a> est toujours appliqué après <a class=\"reference internal\" href=\"#django.test.override_settings\" title=\"django.test.override_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">override_settings()</span></code></a>.</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Le fichier de réglages contient certains réglages qui ne sont consultés que lors de l’initialisation de paramètres internes à Django. Si vous les modifier avec <code class=\"docutils literal notranslate\"><span class=\"pre\">override_settings</span></code>, ces réglages sont bien modifiés si vous les appelez depuis le module <code class=\"docutils literal notranslate\"><span class=\"pre\">django.conf.settings</span></code>, mais les éléments internes de Django accèdent différemment à ces réglages. En pratique, l’utilisation de <a class=\"reference internal\" href=\"#django.test.override_settings\" title=\"django.test.override_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">override_settings()</span></code></a> ou de <a class=\"reference internal\" href=\"#django.test.modify_settings\" title=\"django.test.modify_settings\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">modify_settings()</span></code></a> avec ces réglages ne va probablement pas avoir l’effet que vous attendez.</p>\n<p>Il n’est pas recommandé de modifier le réglage <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASES</span></code></a>. La modification du réglage <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a> est possible, mais un peu délicat si vous utilisez des éléments internes qui s’appuient sur du cache, comme <a class=\"reference internal\" href=\"/fr/3.2/topics/http/sessions/#module-django.contrib.sessions\" title=\"django.contrib.sessions: Provides session management for Django projects.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.sessions</span></code></a>. Par exemple, il faut réinitialiser le moteur de sessions dans un test qui utilise les sessions en cache et qui surcharge <a class=\"reference internal\" href=\"/fr/3.2/ref/settings/#std-setting-CACHES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CACHES</span></code></a>.</p>\n<p>Pour terminer, évitez de créer des alias de réglages comme constantes de niveau module, car <code class=\"docutils literal notranslate\"><span class=\"pre\">override_settings()</span></code> ne fonctionnera pas avec de telles valeurs qui ne sont évaluées que lors de la première importation du module.</p>\n</aside>\n<p>Il est aussi possible de simuler l’absence d’un réglage en supprimant celui-ci après que les réglages aient été surchargés, comme ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@override_settings</span><span class=\"p\">()</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_something</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">del</span> <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">LOGIN_URL</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Lors de la surcharge de réglages, prenez soin de gérer les cas où le code de votre application utilise du cache ou un mécanisme similaire conservant l’état même quand le réglage a changé. Django fournit le signal <a class=\"reference internal\" href=\"/fr/3.2/ref/signals/#django.test.signals.setting_changed\" title=\"django.test.signals.setting_changed\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.test.signals.setting_changed</span></code></a> permettant d’inscrire des fonctions de rappel qui serviront à réinitialiser l’état lorsque les réglages ont changé.</p>\n<p>Django utilise lui-même ce signal pour réinitialiser différentes données :</p>\n<div class=\"table-scroll\" role=\"region\" tabindex=\"0\" aria-label=\"Table\"><table class=\"docutils align-default\">\n<thead>\n<tr class=\"row-odd\"><th class=\"head\"><p>Réglages surchargés</p></th>\n<th class=\"head\"><p>Données réinitialisées</p></th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"row-even\"><td><p>USE_TZ, TIME_ZONE</p></td>\n<td><p>Fuseau horaire de la base de données</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p>TEMPLATES</p></td>\n<td><p>Moteurs de gabarits</p></td>\n</tr>\n<tr class=\"row-even\"><td><p>SERIALIZATION_MODULES</p></td>\n<td><p>Cache des sérialiseurs</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p>LOCALE_PATHS, LANGUAGE_CODE</p></td>\n<td><p>Traduction par défaut et traductions chargées</p></td>\n</tr>\n<tr class=\"row-even\"><td><p>MEDIA_ROOT, DEFAULT_FILE_STORAGE</p></td>\n<td><p>Stockage de fichiers par défaut</p></td>\n</tr>\n</tbody>\n</table>\n</div>\n</section>\n<section id=\"emptying-the-test-outbox\">\n<span id=\"emptying-test-outbox\"></span><h3>Vidage de la boîte de messagerie de test<a class=\"heading-anchor\" href=\"#emptying-the-test-outbox\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous utilisez l’une des classes <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> personnalisées de Django, l’exécuteur de tests efface le contenu de la boîte de messagerie de test au début de chaque cas de test.</p>\n<p>Pour plus de détails sur les services de messagerie durant les tests, consultez <a class=\"reference internal\" href=\"#email-services\">Services de messagerie</a> plus bas dans ce document.</p>\n</section>\n<section id=\"assertions\">\n<span id=\"id2\"></span><h3>Assertions<a class=\"heading-anchor\" href=\"#assertions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>De la même manière que la classe <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">unittest.TestCase</span></code></a> normale de Python implément des méthodes d’assertion telles que <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertTrue\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertTrue()</span></code></a> et <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertEqual\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertEqual()</span></code></a>, la classe <a class=\"reference internal\" href=\"#django.test.TestCase\" title=\"django.test.TestCase\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TestCase</span></code></a> propre à Django fournit un certain nombre de méthodes d’assertion utiles pour tester les applications Web :</p>\n<p>Les messages d’échec produits par la plupart de ces méthodes d’assertion peuvent être personnalisés par le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg_prefix</span></code>. Cette chaîne préfixe tout message d’échec généré par l’assertion. Ceci permet d’ajouter des détails pouvant aider à identifier l’emplacement et la cause d’un échec dans une suite de tests.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertRaisesMessage\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertRaisesMessage</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_exception</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_message</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">callable</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">args</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertRaisesMessage\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dt class=\"sig sig-object py\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertRaisesMessage</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_exception</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_message</span></span></em><span class=\"sig-paren\">)</span></dt>\n<dd><p>Confirme que l’appel à l’exécutable <code class=\"docutils literal notranslate\"><span class=\"pre\">callable</span></code> génère l’exception <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_exception</span></code> et que <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_message</span></code> est trouvé dans le message de l’exception. Tout autre résultat est signalé comme un échec. Il s’agit d’une version simplifiée de <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaisesRegex\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">unittest.TestCase.assertRaisesRegex()</span></code></a>, à la différence près que <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_message</span></code> n’est ici pas traité comme une expression régulière.</p>\n<p>Si seuls les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_exception</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_message</span></code> sont donnés, renvoie un gestionnaire de contexte afin que le code en cours de test puisse être écrit en ligne plutôt que sous la forme d’une fonction :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRaisesMessage</span><span class=\"p\">(</span><span class=\"ne\">ValueError</span><span class=\"p\">,</span> <span class=\"s1\">&#39;invalid literal for int()&#39;</span><span class=\"p\">):</span>\n    <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"s1\">&#39;a&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertWarnsMessage\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertWarnsMessage</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_warning</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_message</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">callable</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">args</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertWarnsMessage\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dt class=\"sig sig-object py\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertWarnsMessage</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_warning</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_message</span></span></em><span class=\"sig-paren\">)</span></dt>\n<dd><p>Analogue à <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertRaisesMessage\" title=\"django.test.SimpleTestCase.assertRaisesMessage\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">SimpleTestCase.assertRaisesMessage()</span></code></a> mais pour <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertWarnsRegex\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertWarnsRegex()</span></code></a> au lieu de <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaisesRegex\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertRaisesRegex()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertFieldOutput\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertFieldOutput</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fieldclass</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">valid</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">invalid</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field_args</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field_kwargs</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">empty_value</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertFieldOutput\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme qu’un champ de formulaire se comporte correctement avec différentes valeurs soumises.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Paramètres<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>fieldclass</strong> – la classe du champ à tester.</p></li>\n<li><p><strong>valid</strong> – un dictionnaire faisant correspondre des valeurs de saisies valides aux valeurs nettoyées attendues.</p></li>\n<li><p><strong>invalid</strong> – un dictionnaire faisant correspondre des valeurs de saisies non valides à un ou plusieurs messages d’erreur attendus.</p></li>\n<li><p><strong>field_args</strong> – les paramètres positionnels transmis pour la création du champ.</p></li>\n<li><p><strong>field_kwargs</strong> – les paramètres nommés transmis pour la création du champ.</p></li>\n<li><p><strong>empty_value</strong> – le résultat nettoyé attendu pour les valeurs saisies contenues dans <code class=\"docutils literal notranslate\"><span class=\"pre\">empty_values</span></code>.</p></li>\n</ul>\n</dd>\n</dl>\n<p>Par exemple, le code suivant teste qu’un champ <code class=\"docutils literal notranslate\"><span class=\"pre\">EmailField</span></code> accepte <code class=\"docutils literal notranslate\"><span class=\"pre\">a&#64;a.com</span></code> comme adresse électronique valide, mais rejette <code class=\"docutils literal notranslate\"><span class=\"pre\">aaa</span></code> avec un message d’erreur adéquat :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertFieldOutput</span><span class=\"p\">(</span><span class=\"n\">EmailField</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;a@a.com&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;a@a.com&#39;</span><span class=\"p\">},</span> <span class=\"p\">{</span><span class=\"s1\">&#39;aaa&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;Enter a valid email address.&#39;</span><span class=\"p\">]})</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertFormError\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertFormError</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">form</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">errors</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertFormError\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme qu’un champ de formulaire génère la liste d’erreurs fournie lorsqu’il est affiché dans son formulaire.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">form</span></code> est le nom de l’instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Form</span></code> dans le contexte de gabarit.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">field</span></code> est le nom du champ dans le formulaire à contrôler. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">field</span></code> possède la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, ce sont les erreurs non liées aux formulaires (accessibles via <a class=\"reference internal\" href=\"/fr/3.2/ref/forms/api/#django.forms.Form.non_field_errors\" title=\"django.forms.Form.non_field_errors\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">form.non_field_errors()</span></code></a>) qui seront vérifiées.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">errors</span></code> est un texte d’erreur ou une liste de textes d’erreur qui sont censés être produits en réponse à la validation du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertFormsetError\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertFormsetError</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">formset</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">form_index</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">errors</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertFormsetError\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que <code class=\"docutils literal notranslate\"><span class=\"pre\">formset</span></code> génère la liste d’erreurs fournie lorsqu’il est affiché.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">formset</span></code> est le nom de l’instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Formset</span></code> dans le contexte de gabarit.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">form_index</span></code> est le numéro du formulaire dans <code class=\"docutils literal notranslate\"><span class=\"pre\">Formset</span></code>. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">form_index</span></code> possède la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, ce sont les erreurs non liées aux formulaires (accessibles via <code class=\"docutils literal notranslate\"><span class=\"pre\">formset.non_form_errors()</span></code>) qui seront vérifiées.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">field</span></code> est le nom du champ dans le formulaire à contrôler. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">field</span></code> possède la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, ce sont les erreurs non liées aux formulaires (accessibles via <a class=\"reference internal\" href=\"/fr/3.2/ref/forms/api/#django.forms.Form.non_field_errors\" title=\"django.forms.Form.non_field_errors\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">form.non_field_errors()</span></code></a>) qui seront vérifiées.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">errors</span></code> est un texte d’erreur ou une liste de textes d’erreur qui sont censés être produits en réponse à la validation du formulaire.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertContains\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertContains</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">text</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">count</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">status_code</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">200</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertContains\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme qu’une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code> produit le code <code class=\"docutils literal notranslate\"><span class=\"pre\">status_code</span></code> indiqué et que le contenu <code class=\"docutils literal notranslate\"><span class=\"pre\">text</span></code> apparaît dans le contenu de la réponse. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code> est renseigné, <code class=\"docutils literal notranslate\"><span class=\"pre\">text</span></code> doit apparaître exactement <code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code> fois dans la réponse.</p>\n<p>Définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">html</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> pour que <code class=\"docutils literal notranslate\"><span class=\"pre\">text</span></code> soit géré comme du code HTML. La comparaison avec le contenu de la réponse prend alors en compte la sémantique HTML au lieu d’une comparaison caractère par caractère. Les espaces blancs sont majoritairement ignorés et l’ordre des attributs ne joue pas de rôle. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertHTMLEqual()</span></code></a> pour plus de détails.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertNotContains\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertNotContains</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">text</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">status_code</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">200</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertNotContains\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme qu’une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">Response</span></code> produit le code <code class=\"docutils literal notranslate\"><span class=\"pre\">status_code</span></code> indiqué et que le contenu <code class=\"docutils literal notranslate\"><span class=\"pre\">text</span></code> n’apparaît <em>pas</em> dans le contenu de la réponse.</p>\n<p>Définissez <code class=\"docutils literal notranslate\"><span class=\"pre\">html</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> pour que <code class=\"docutils literal notranslate\"><span class=\"pre\">text</span></code> soit géré comme du code HTML. La comparaison avec le contenu de la réponse prend alors en compte la sémantique HTML au lieu d’une comparaison caractère par caractère. Les espaces blancs sont majoritairement ignorés et l’ordre des attributs ne joue pas de rôle. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertHTMLEqual()</span></code></a> pour plus de détails.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertTemplateUsed\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertTemplateUsed</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">template_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">count</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertTemplateUsed\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que le gabarit du nom indiqué a été utilisé pour produire la réponse.</p>\n<p>Le nom est une chaîne du genre <code class=\"docutils literal notranslate\"><span class=\"pre\">'admin/index.html'</span></code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code> est un nombre entier indiquant le nombre de fois qu’un gabarit doit être produit. La valeur par défaut est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, ce qui signifie que le gabarit doit être produit une ou plusieurs fois.</p>\n<p>Vous pouvez l’utiliser comme un gestionnaire de contexte, comme ceci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertTemplateUsed</span><span class=\"p\">(</span><span class=\"s1\">&#39;index.html&#39;</span><span class=\"p\">):</span>\n    <span class=\"n\">render_to_string</span><span class=\"p\">(</span><span class=\"s1\">&#39;index.html&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertTemplateUsed</span><span class=\"p\">(</span><span class=\"n\">template_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index.html&#39;</span><span class=\"p\">):</span>\n    <span class=\"n\">render_to_string</span><span class=\"p\">(</span><span class=\"s1\">&#39;index.html&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertTemplateNotUsed\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertTemplateNotUsed</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">template_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertTemplateNotUsed\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que le gabarit du nom indiqué n’a <em>pas</em> été utilisé pour produire la réponse.</p>\n<p>Vous pouvez l’utiliser comme un gestionnaire de contexte de la même façon qu’avec <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertTemplateUsed\" title=\"django.test.SimpleTestCase.assertTemplateUsed\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertTemplateUsed()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertURLEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertURLEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">url1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">url2</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertURLEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que deux URL sont identiques, en ignorant l’ordre des paramètres de requête à l’exception des paramètres de même nom. Par exemple, <code class=\"docutils literal notranslate\"><span class=\"pre\">/chemin/?x=1&amp;y=2</span></code> est égal à <code class=\"docutils literal notranslate\"><span class=\"pre\">/chemin/?y=2&amp;x=1</span></code>, mais <code class=\"docutils literal notranslate\"><span class=\"pre\">/chemin/?a=1&amp;a=2</span></code> n’est pas égal à <code class=\"docutils literal notranslate\"><span class=\"pre\">/chemin/?a=2&amp;a=1</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertRedirects\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertRedirects</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">response</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_url</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">status_code</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">302</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">target_status_code</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">200</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fetch_redirect_response</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertRedirects\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que la réponse renvoie un statut de redirection <code class=\"docutils literal notranslate\"><span class=\"pre\">status_code</span></code>, qu’elle redirige vers <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_url</span></code> (y compris avec d’éventuelles données <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code>) et que la page finale a renvoyé le code <code class=\"docutils literal notranslate\"><span class=\"pre\">target_status_code</span></code>.</p>\n<p>Si la requête a utilisé le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code>, les valeurs de <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_url</span></code> et de <code class=\"docutils literal notranslate\"><span class=\"pre\">target_status_code</span></code> doivent être celles de la page finale de la chaîne de redirection.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">fetch_redirect_response</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, la page finale n’est pas chargée. Comme le client de test ne peut pas récupérer des URL externes, c’est particulièrement utile quand <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_url</span></code> ne fait pas partie de votre application Django.</p>\n<p>Le protocole est géré correctement lors de comparaisons entre deux URL. Si aucun protocole n’est indiqué à l’emplacement de redirection, le protocole de la requête d’origine est utilisé. S’il est présent, le protocole dans <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_url</span></code> est celui qui sera utilisé pour effectuer des comparaisons.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertHTMLEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertHTMLEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html2</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les chaînes <code class=\"docutils literal notranslate\"><span class=\"pre\">html1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">html2</span></code> sont équivalentes. La comparaison prend en compte la sémantique HTML. La comparaison tient compte des éléments suivants :</p>\n<ul class=\"simple\">\n<li><p>Les blancs avant et après les balises HTML sont ignorés.</p></li>\n<li><p>Tous les types de blancs (espaces, tabulateurs, etc.) sont équivalents.</p></li>\n<li><p>Toutes les balises ouvertes sont fermées implicitement, par exemple quand une balise de niveau supérieur est fermée ou quand le document HTML est fini.</p></li>\n<li><p>Les balises vides sont équivalentes à leur version auto-fermante.</p></li>\n<li><p>L’ordre des attributs d’un élément HTML n’est pas signifiant.</p></li>\n<li><p>Les attributs sans paramètre sont équivalents aux attributs dont le nom et la valeur sont identiques (voir les exemples).</p></li>\n<li><p>Le texte, les références de caractères et les références d’entité qui se réfèrent au même caractère sont équivalents.</p></li>\n</ul>\n<p>Les exemples suivants sont des tests valides et ne génèrent pas d’exception <code class=\"docutils literal notranslate\"><span class=\"pre\">AssertionError</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertHTMLEqual</span><span class=\"p\">(</span>\n    <span class=\"s1\">&#39;&lt;p&gt;Hello &lt;b&gt;&amp;#x27;world&amp;#x27;!&lt;/p&gt;&#39;</span><span class=\"p\">,</span>\n<span class=\"w\">    </span><span class=\"sd\">&#39;&#39;&#39;&lt;p&gt;</span>\n<span class=\"sd\">        Hello   &lt;b&gt;&amp;#39;world&amp;#39;! &lt;/b&gt;</span>\n<span class=\"sd\">    &lt;/p&gt;&#39;&#39;&#39;</span>\n<span class=\"p\">)</span>\n<span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertHTMLEqual</span><span class=\"p\">(</span>\n    <span class=\"s1\">&#39;&lt;input type=&quot;checkbox&quot; checked=&quot;checked&quot; id=&quot;id_accept_terms&quot; /&gt;&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;&lt;input id=&quot;id_accept_terms&quot; type=&quot;checkbox&quot; checked&gt;&#39;</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">html1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">html2</span></code> doivent contenir du code HTML. Une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">AssertionError</span></code> est générée si l’une de ces deux valeurs ne peut pas être analysée comme du code HTML.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertHTMLNotEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertHTMLNotEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">html2</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertHTMLNotEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les chaînes <code class=\"docutils literal notranslate\"><span class=\"pre\">html1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">html2</span></code> ne sont <em>pas</em> équivalentes. La comparaison prend en compte la sémantique HTML. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertHTMLEqual()</span></code></a> pour plus de détails.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">html1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">html2</span></code> doivent contenir du code HTML. Une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">AssertionError</span></code> est générée si l’une de ces deux valeurs ne peut pas être analysée comme du code HTML.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertXMLEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertXMLEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">xml1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">xml2</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertXMLEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les chaînes <code class=\"docutils literal notranslate\"><span class=\"pre\">xml1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">xml2</span></code> sont équivalentes. La comparaison prend en compte la sémantique XML. Sur le même principe que <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertHTMLEqual()</span></code></a>, la comparaison se fait sur le contenu analysé, ce qui fait que seules les différences sémantiques sont prises en compte, pas la syntaxe elle-même. Si le contenu XML de l’un des paramètres n’est pas valide, une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">AssertionError</span></code> est toujours générée, même si les deux chaînes sont identiques.</p>\n<p>La déclaration XML, le type de document, les instructions de traitement et les commentaires sont ignorés. Seul l’élément racine (root) et ses descendants sont comparés.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertXMLNotEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertXMLNotEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">xml1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">xml2</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertXMLNotEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les chaînes <code class=\"docutils literal notranslate\"><span class=\"pre\">xml1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">xml2</span></code> ne sont <em>pas</em> équivalentes. La comparaison prend en compte la sémantique xML. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertXMLEqual\" title=\"django.test.SimpleTestCase.assertXMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertXMLEqual()</span></code></a> pour plus de détails.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertInHTML\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertInHTML</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">needle</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">haystack</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">count</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg_prefix</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">''</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertInHTML\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que le fragment HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">needle</span></code> est contenu dans le contenu <code class=\"docutils literal notranslate\"><span class=\"pre\">haystack</span></code>.</p>\n<p>Si le paramètre nombre entier <code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code> est indiqué, un contrôle supplémentaire est effectué que le nombre d’occurrences de <code class=\"docutils literal notranslate\"><span class=\"pre\">needle</span></code> correspond à <code class=\"docutils literal notranslate\"><span class=\"pre\">count</span></code>.</p>\n<p>Dans la plupart des cas, les blancs sont ignorés et l’ordre des attributs n’est pas pris en compte. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertHTMLEqual\" title=\"django.test.SimpleTestCase.assertHTMLEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertHTMLEqual()</span></code></a> pour plus de détails.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertJSONEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertJSONEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">raw</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_data</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertJSONEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les fragments JSON <code class=\"docutils literal notranslate\"><span class=\"pre\">raw</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_data</span></code> sont égaux. Les règles habituelles de JSON concernant les blancs non significatifs s’appliquent, car le gros du travail est confié à la bibliothèque <a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#module-json\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">json</span></code></a>.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.SimpleTestCase.assertJSONNotEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SimpleTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertJSONNotEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">raw</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">expected_data</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.SimpleTestCase.assertJSONNotEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que les fragments JSON <code class=\"docutils literal notranslate\"><span class=\"pre\">raw</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">expected_data</span></code> <em>ne sont pas</em> égaux. Voir <a class=\"reference internal\" href=\"#django.test.SimpleTestCase.assertJSONEqual\" title=\"django.test.SimpleTestCase.assertJSONEqual\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertJSONEqual()</span></code></a> pour plus de détails.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.TransactionTestCase.assertQuerysetEqual\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">TransactionTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertQuerysetEqual</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">qs</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">values</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">transform</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">ordered</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">msg</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.TransactionTestCase.assertQuerysetEqual\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que le jeu de requête <code class=\"docutils literal notranslate\"><span class=\"pre\">qs</span></code> correspond à une itération particulière de valeurs <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code>.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">transform</span></code> est indiqué, <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code> est comparé à une liste produite en appliquant <code class=\"docutils literal notranslate\"><span class=\"pre\">transform</span></code> à chaque membre de <code class=\"docutils literal notranslate\"><span class=\"pre\">qs</span></code>.</p>\n<p>Par défaut, la comparaison dépend aussi de l’ordre de tri. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">qs</span></code> ne comporte pas d’ordre de tri implicite, vous pouvez définir le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">ordered</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, ce qui provoquera une comparaison sur des objets <code class=\"docutils literal notranslate\"><span class=\"pre\">collections.Counter</span></code>. Si l’ordre est indéfini (si le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">qs</span></code> n’est pas trié et que la comparaison se fait avec plus d’une valeur triée) une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">ValueError</span></code> est générée.</p>\n<p>L’affichage en cas d’erreur peut être personnalisé avec le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">msg</span></code>.</p>\n<aside class=\"version-note version-changed\" data-version=\"3.2\">\n<p class=\"version-note-title\">Changed in Django 3.2</p><p>La valeur par défaut de l’argument <code class=\"docutils literal notranslate\"><span class=\"pre\">transform</span></code> est passée à <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n</aside>\n<aside class=\"version-note version-added\" data-version=\"3.2\">\n<p class=\"version-note-title\">New in Django 3.2</p><p>La prise en charge de la comparaison directe entre jeux de requête a été ajoutée.</p>\n</aside>\n<aside class=\"version-note version-deprecated\" data-version=\"3.2\">\n<p class=\"version-note-title\">Deprecated since Django 3.2</p><p><span class=\"versionmodified deprecated\">Obsolète depuis la version 3.2: </span>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">transform</span></code> n’est pas fourni et que <code class=\"docutils literal notranslate\"><span class=\"pre\">values</span></code> est une liste de chaînes, la comparaison se fait avec une liste produite en appliquant  <code class=\"docutils literal notranslate\"><span class=\"pre\">repr()</span></code> à chaque membre de <code class=\"docutils literal notranslate\"><span class=\"pre\">qs</span></code>. Ce comportement est obsolète et sera supprimé dans Django 4.1. Si vous souhaitez le conserver, définissez explicitement <code class=\"docutils literal notranslate\"><span class=\"pre\">transform</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">repr</span></code>.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.test.TransactionTestCase.assertNumQueries\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">TransactionTestCase.</span></span><span class=\"sig-name descname\"><span class=\"pre\">assertNumQueries</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">num</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">func</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">args</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.TransactionTestCase.assertNumQueries\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Confirme que lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">func</span></code> est appelée avec <code class=\"docutils literal notranslate\"><span class=\"pre\">*args</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">num</span></code> requêtes de base de données sont effectuées.</p>\n<p>Si une clé <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;using&quot;</span></code> est présente dans <code class=\"docutils literal notranslate\"><span class=\"pre\">kwargs</span></code>, cette valeur est utilisée comme alias de base de données pour laquelle le nombre de requêtes sera contrôlé</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertNumQueries</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s1\">&#39;non_default_db&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous souhaitez appeler une fonction avec un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code>, vous pouvez le faire en enveloppant l’appel dans une fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">lambda</span></code> pour y ajouter un paramètre supplémentaire</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertNumQueries</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"k\">lambda</span><span class=\"p\">:</span> <span class=\"n\">my_function</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Vous pouvez également l’utiliser comme un gestionnaire de contexte :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertNumQueries</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">):</span>\n    <span class=\"n\">Person</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Aaron&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">Person</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Daniel&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n</section>\n<section id=\"tagging-tests\">\n<span id=\"topics-tagging-tests\"></span><h3>Étiquetage des tests<a class=\"heading-anchor\" href=\"#tagging-tests\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il est possible d’étiqueter les tests afin de pouvoir plus facilement lancer un sous-ensemble particulier. Par exemple, vous pourriez étiqueter les tests rapides ou lents :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">tag</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SampleTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;fast&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_fast</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;slow&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_slow</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n\n    <span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;slow&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;core&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_slow_but_core</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>Il est aussi possible d’étiqueter un cas de test :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;slow&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;core&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SampleTestCase</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Les sous-classes héritent des classes parentes, et les méthodes héritent des étiquettes de leur classe. Par exemple</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SampleTestCaseChild</span><span class=\"p\">(</span><span class=\"n\">SampleTestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">SampleTestCaseChild.test</span></code> possédera les étiquettes <code class=\"docutils literal notranslate\"><span class=\"pre\">'slow'</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">'core'</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">'bar'</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">'foo'</span></code>.</p>\n<p>Puis, vous pouvez choisir quels tests lancer. Par exemple, pour ne lancer que les tests rapides :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-2-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./manage.py<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>--tag<span class=\"o\">=</span>fast\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-2-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> manage.py test --tag=fast\n</code></pre></div></div></div>\n<p>Ou pour lancer les tests rapides et les tests principaux (même s’ils sont lents) :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-3-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./manage.py<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>--tag<span class=\"o\">=</span>fast<span class=\"w\"> </span>--tag<span class=\"o\">=</span>core\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-3-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> manage.py test --tag=fast --tag=core\n</code></pre></div></div></div>\n<p>Il est aussi possible d’exclure des tests par leur étiquette. Pour lancer les tests principaux qui ne sont pas lents :</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-4-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./manage.py<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>--tag<span class=\"o\">=</span>core<span class=\"w\"> </span>--exclude-tag<span class=\"o\">=</span>slow\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-4-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> manage.py test --tag=core --exclude-tag=slow\n</code></pre></div></div></div>\n<p><a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#cmdoption-test-exclude-tag\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">test</span> <span class=\"pre\">--exclude-tag</span></code></a> a la priorité sur <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#cmdoption-test-tag\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">test</span> <span class=\"pre\">--tag</span></code></a>, si donc un test possède deux étiquettes et que vous choisissez l’une d’elle tout en excluant l’autre, le test ne sera pas lancé.</p>\n</section>\n</section>\n<section id=\"testing-asynchronous-code\">\n<span id=\"async-tests\"></span><h2>Test de code asynchrone<a class=\"heading-anchor\" href=\"#testing-asynchronous-code\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"version-note version-added\" data-version=\"3.1\">\n<p class=\"version-note-title\">New in Django 3.1</p></aside>\n<p>Si vous souhaitez simplement tester le résultat de vues asynchrones, le client de test standard les lance dans une boucle asynchrone dédiée sans travail supplémentaire de votre part.</p>\n<p>Cependant, si vous souhaitez écrire des tests pleinement asynchrones pour un projet Django, vous devrez prendre en compte plusieurs choses.</p>\n<p>Tout d’abord, vos tests doivent être des méthodes <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> de la classe de test (afin de leur fournir un contexte asynchrone). Django détectera automatiquement tout test de type <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> et les enveloppera afin qu’ils s’exécutent dans leur propre boucle événementielle.</p>\n<p>Si vous testez depuis une fonction asynchrone, vous devez éaglement utiliser le client de test asynchrone. Il est disponible comme <code class=\"docutils literal notranslate\"><span class=\"pre\">django.test.AsyncClient</span></code> ou comme <code class=\"docutils literal notranslate\"><span class=\"pre\">self.async_client</span></code> dans chaque test.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">AsyncClient</span></code> possède les mêmes méthodes et signatures que le client de test synchrone (normal), avec deux exceptions :</p>\n<ul>\n<li><p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">follow</span></code> n’est pas pris en charge.</p></li>\n<li><p>Les en-têtes transmis dans le paramètre nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">extra</span></code> ne doivent pas comporter de préfixe <code class=\"docutils literal notranslate\"><span class=\"pre\">HTTP_</span></code> tel que requis par le client synchrone (voir <a class=\"reference internal\" href=\"#django.test.Client.get\" title=\"django.test.Client.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Client.get()</span></code></a>). Par exemple, voici comment définir un en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Accept</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">AsyncClient</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">c</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"s1\">&#39;/customers/details/&#39;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"p\">{</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;fred&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;age&#39;</span><span class=\"p\">:</span> <span class=\"mi\">7</span><span class=\"p\">},</span>\n<span class=\"gp\">... </span>    <span class=\"n\">ACCEPT</span><span class=\"o\">=</span><span class=\"s1\">&#39;application/json&#39;</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n</ul>\n<p>En utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">AsyncClient</span></code>, toute méthode effectuant une requête doit être appelée avec <code class=\"docutils literal notranslate\"><span class=\"pre\">await</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_my_thing</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">async_client</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;/some-url/&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">status_code</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le client asynchrone peut aussi appeler des vues synchrones ; il s’exécute au travers du <a class=\"reference internal\" href=\"/fr/3.2/topics/async/\"><span class=\"doc\">chemin de requête asynchrone</span></a> de Django, qui prend en charge les deux modes. Toute vue appelée par <code class=\"docutils literal notranslate\"><span class=\"pre\">AsyncClient</span></code> reçoit un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">ASGIRequest</span></code> dans son attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> au lieu de l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIRequest</span></code> créé par le client normal.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si vous utilisez des décorateurs de tests, ils doivent être compatibles avec l’asynchrone pour fonctionner correctement. Les décorateurs intégrés de Django se comporteront correctement, mais ceux de tierces parties peuvent sembler ne pas s’exécuter (ils « enveloppent » la mauvaise partie du flux d’exécution au lieu de votre test).</p>\n<p>Si vous avez besoin d’utiliser ces décorateurs, vous devez alors plutôt décorer vos méthodes de test avec <a class=\"reference internal\" href=\"/fr/3.2/topics/async/#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> <em>à l’intérieur</em> de celles-ci :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">async_to_sync</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@mock</span><span class=\"o\">.</span><span class=\"n\">patch</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"nd\">@async_to_sync</span>\n    <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_my_thing</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n</aside>\n</section>\n<section id=\"email-services\">\n<span id=\"topics-testing-email\"></span><h2>Services de messagerie<a class=\"heading-anchor\" href=\"#email-services\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si l’une de vos vues Django envoie des courriels via la <a class=\"reference internal\" href=\"/fr/3.2/topics/email/\"><span class=\"doc\">fonctionnalité d’envoi de courriels de Django</span></a>, vous ne souhaiterez probablement pas réellement envoyer un courriel lors de chaque test de cette vue. C’est pour cette raison que le lanceur de tests de Django redirige automatiquement tous les courriels qu’il envoie dans une boîte artificielle. Cela vous permet aussi de tester chaque aspect de l’envoi de courriels, du nombre de messages envoyés jusqu’au contenu de chaque message, sans jamais envoyer réellement les messages.</p>\n<p>Le lanceur de tests fait cela en remplaçant de manière transparente le moteur de messagerie normal par un moteur de test (n’ayez crainte, cela n’a aucun effet sur l’expédition de courriels en dehors de Django, comme un éventuel serveur de messagerie tournant sur votre machine).</p>\n<dl class=\"py data\">\n<dt class=\"sig sig-object py\" id=\"django.core.mail.django.core.mail.outbox\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.mail.</span></span><span class=\"sig-name descname\"><span class=\"pre\">outbox</span></span><a class=\"heading-anchor\" href=\"#django.core.mail.django.core.mail.outbox\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Durant le fonctionnement des tests, chaque courriel sortant est enregistré dans <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.mail.outbox</span></code>. Il s’agit d’une liste de toutes les instances de <a class=\"reference internal\" href=\"/fr/3.2/topics/email/#django.core.mail.EmailMessage\" title=\"django.core.mail.EmailMessage\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">EmailMessage</span></code></a> qui ont été envoyées. L’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">outbox</span></code> est un attribut spécial qui est <em>uniquement</em> créé lorsque le moteur de messagerie <code class=\"docutils literal notranslate\"><span class=\"pre\">locmem</span></code> est actif. Il ne fait normalement pas partie du module <a class=\"reference internal\" href=\"/fr/3.2/topics/email/#module-django.core.mail\" title=\"django.core.mail: Helpers to easily send email.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.core.mail</span></code></a> et il ne peut être importé directement. Le code ci-dessous montre comment accéder correctement à cet attribut.</p>\n<p>Voici un exemple de test qui examine la longueur et le contenu de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.mail.outbox</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">mail</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">EmailTest</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_send_email</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Send message.</span>\n        <span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">send_mail</span><span class=\"p\">(</span>\n            <span class=\"s1\">&#39;Subject here&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Here is the message.&#39;</span><span class=\"p\">,</span>\n            <span class=\"s1\">&#39;from@example.com&#39;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s1\">&#39;to@example.com&#39;</span><span class=\"p\">],</span>\n            <span class=\"n\">fail_silently</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n        <span class=\"p\">)</span>\n\n        <span class=\"c1\"># Test that one message has been sent.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Verify that the subject of the first message is correct.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">subject</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Subject here&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Comme noté <a class=\"reference internal\" href=\"#emptying-test-outbox\"><span class=\"std std-ref\">précédemment</span></a>, la boîte de messagerie de test est vidée au début de chaque test des classes Django <code class=\"docutils literal notranslate\"><span class=\"pre\">*TestCase</span></code>. Pour vider la boîte manuellement, attribuez une liste vide à <code class=\"docutils literal notranslate\"><span class=\"pre\">mail.outbox</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">mail</span>\n\n<span class=\"c1\"># Empty the test outbox</span>\n<span class=\"n\">mail</span><span class=\"o\">.</span><span class=\"n\">outbox</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n</code></pre></div>\n</section>\n<section id=\"management-commands\">\n<span id=\"topics-testing-management-commands\"></span><h2>Commandes d’administration<a class=\"heading-anchor\" href=\"#management-commands\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les commandes d’administration peuvent être testées avec la fonction <a class=\"reference internal\" href=\"/fr/3.2/ref/django-admin/#django.core.management.call_command\" title=\"django.core.management.call_command\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">call_command()</span></code></a>. La sortie peut être redirigée vers une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">StringIO</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">io</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">StringIO</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.management</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">call_command</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TestCase</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ClosepollTest</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_command_output</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"n\">StringIO</span><span class=\"p\">()</span>\n        <span class=\"n\">call_command</span><span class=\"p\">(</span><span class=\"s1\">&#39;closepoll&#39;</span><span class=\"p\">,</span> <span class=\"n\">stdout</span><span class=\"o\">=</span><span class=\"n\">out</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertIn</span><span class=\"p\">(</span><span class=\"s1\">&#39;Expected output&#39;</span><span class=\"p\">,</span> <span class=\"n\">out</span><span class=\"o\">.</span><span class=\"n\">getvalue</span><span class=\"p\">())</span>\n</code></pre></div>\n</section>\n<section id=\"skipping-tests\">\n<span id=\"id3\"></span><h2>Exclusion de tests<a class=\"heading-anchor\" href=\"#skipping-tests\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La bibliothèque unittest fournit les décorateurs <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.skipIf\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">&#64;skipIf</span></code></a> rz <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.skipUnless\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">&#64;skipUnless</span></code></a> pour permettre d’exclure des tests si vous savez à l’avance que ces tests vont échouer dans certaines conditions.</p>\n<p>Par exemple, si la réussite d’un test exige la présence d’une certaine bibliothèque, il est possible de décorer le cas de test avec  <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.skipIf\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">&#64;skipIf</span></code></a>. Puis, le lanceur de tests signalera que le test n’a pas été exécuté ainsi que la raison, au lieu de laisser le test échouer ou d’ignorer totalement le test.</p>\n<p>En plus de ces comportements d’exclusion de test, Django ajoute deux décorateurs de test supplémentaires. Au lieu de se baser sur une valeur booléenne générique, ces décorateurs contrôlent les capacités d’une base de données et excluent le test concerné si la base de données ne gère pas la capacité nommément indiquée.</p>\n<p>Ces décorateurs utilisent un identifiant textuel pour désigner les capacités de base de données. Cet identifiant correspond à un attribut de la classe des capacités de connexion de base de données. Voir <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/3.2.x/django/db/backends/base/features.py\">la classe django.db.backends.base.features.BaseDatabaseFeatures</a> pour obtenir une liste complète des capacités de base de données pouvant être utilisées comme critères d’exclusion de tests.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.test.skipIfDBFeature\">\n<span class=\"sig-name descname\"><span class=\"pre\">skipIfDBFeature</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">feature_name_strings</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.skipIfDBFeature\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Exclut le test ou la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> décorés si toutes les capacités de base de données indiquées sont prises en charge.</p>\n<p>Par exemple, le test suivant ne sera pas exécuté si la base de données gère les transactions (par ex. il ne serait <em>pas</em> exécuté avec PostgreSQL, mais il le serait avec MySQL utilisant des tables MyISAM) :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"nd\">@skipIfDBFeature</span><span class=\"p\">(</span><span class=\"s1\">&#39;supports_transactions&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_transaction_behavior</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># ... conditional test code</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.test.skipUnlessDBFeature\">\n<span class=\"sig-name descname\"><span class=\"pre\">skipUnlessDBFeature</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">feature_name_strings</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.test.skipUnlessDBFeature\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Exclut le test ou la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">TestCase</span></code> décorés si au moins une des capacités de base de données indiquées <em>n’est pas</em> prise en charge.</p>\n<p>Par exemple, le test suivant ne sera exécuté que si la base de données gère les transactions (par ex. il serait exécuté avec PostgreSQL, mais il ne le serait <em>pas</em> avec MySQL utilisant des tables MyISAM)</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyTests</span><span class=\"p\">(</span><span class=\"n\">TestCase</span><span class=\"p\">):</span>\n    <span class=\"nd\">@skipUnlessDBFeature</span><span class=\"p\">(</span><span class=\"s1\">&#39;supports_transactions&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_transaction_behavior</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># ... conditional test code</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n</section>","rootId":"testing-tools","toc":[{"title":"Le client de test","anchor":"the-test-client","children":[{"title":"Aperçu et exemple rapide","anchor":"overview-and-a-quick-example","children":[]},{"title":"Lancement de requêtes","anchor":"making-requests","children":[]},{"title":"Test des réponses","anchor":"testing-responses","children":[]},{"title":"Exceptions","anchor":"exceptions","children":[]},{"title":"État persistant","anchor":"persistent-state","children":[]},{"title":"Définition de la langue","anchor":"setting-the-language","children":[]},{"title":"Exemple","anchor":"example","children":[]}]},{"title":"Classes de cas de test disponibles","anchor":"provided-test-case-classes","children":[{"title":"SimpleTestCase","anchor":"simpletestcase","children":[]},{"title":"TransactionTestCase","anchor":"transactiontestcase","children":[]},{"title":"TestCase","anchor":"testcase","children":[]},{"title":"LiveServerTestCase","anchor":"liveservertestcase","children":[]}]},{"title":"Fonctionnalités des cas de test","anchor":"test-cases-features","children":[{"title":"Client de test par défaut","anchor":"default-test-client","children":[]},{"title":"Personnalisation du client de test","anchor":"customizing-the-test-client","children":[]},{"title":"Chargement des instantanés","anchor":"fixture-loading","children":[]},{"title":"Configuration des URL","anchor":"urlconf-configuration","children":[]},{"title":"Prise en charge de plusieurs bases de données","anchor":"multi-database-support","children":[]},{"title":"Surcharge des réglages","anchor":"overriding-settings","children":[]},{"title":"Vidage de la boîte de messagerie de test","anchor":"emptying-the-test-outbox","children":[]},{"title":"Assertions","anchor":"assertions","children":[]},{"title":"Étiquetage des tests","anchor":"tagging-tests","children":[]}]},{"title":"Test de code asynchrone","anchor":"testing-asynchronous-code","children":[]},{"title":"Services de messagerie","anchor":"email-services","children":[]},{"title":"Commandes d’administration","anchor":"management-commands","children":[]},{"title":"Exclusion de tests","anchor":"skipping-tests","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/3.2/topics/"},{"docname":"topics/testing/index","title":"Les tests dans Django","url":"/fr/3.2/topics/testing/"}],"prev":{"docname":"topics/testing/overview","title":"Écriture et lancement de tests","url":"/fr/3.2/topics/testing/overview/"},"next":{"docname":"topics/testing/advanced","title":"Thématiques de tests avancées","url":"/fr/3.2/topics/testing/advanced/"},"formats":{"html":"/fr/3.2/topics/testing/tools/","markdown":"/fr/3.2/topics/testing/tools.md","json":"/fr/3.2/topics/testing/tools.json"},"source":"https://github.com/django/django/blob/stable/3.2.x/docs/topics/testing/tools.txt","official":"https://docs.djangoproject.com/fr/3.2/topics/testing/tools/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}