{"id":2587,"date":"2014-11-02T18:41:50","date_gmt":"2014-11-02T16:41:50","guid":{"rendered":"http:\/\/j-mad.com\/blog\/?p=2587"},"modified":"2014-11-02T18:41:50","modified_gmt":"2014-11-02T16:41:50","slug":"django-1-7-et-ecriture-de-tests-petites-explorations","status":"publish","type":"post","link":"https:\/\/j-mad.com\/blog\/2014\/11\/02\/django-1-7-et-ecriture-de-tests-petites-explorations\/","title":{"rendered":"Django 1.7 et \u00e9criture de tests, petites explorations"},"content":{"rendered":"<p>Je me suis enfin lanc\u00e9 dans l&#8217;\u00e9criture d&#8217;une <a href=\"https:\/\/github.com\/mrjmad\/django_badgificator\" target=\"_blank\">app django g\u00e9rant les badge<\/a>s (ou les succ\u00e8s si vous pr\u00e9f\u00e9rez). L&#8217;objectif \u00e9tant de pouvoir r\u00e9\u00e9crire de z\u00e9ro <a href=\"http:\/\/histoiresderolistes.com\/\" target=\"_blank\">histoires de r\u00f4listes<\/a>. L&#8217;id\u00e9e \u00e9tait de tenter de faire une vraie app django, en mode r\u00e9utilisable, histoire que peut-\u00eatre des gens puissent trouver int\u00e9ressant de l&#8217;utiliser.<\/p>\n<p>Je me suis retrouv\u00e9 avec deux probl\u00e8mes concernant mes tests\u00a0:<\/p>\n<ul>\n<li>Souvent on gagne un badge quand on a cr\u00e9\u00e9 suffisamment de chose (comme des checkin, des billets de blogs ou des contributions diverses). Sauf que je ne voulais pas cr\u00e9er dans mon app des models ne servant \u00e0 rien, juste pour pouvoir en cr\u00e9er lors de mes tests.<\/li>\n<li>Je voulais pouvoir cr\u00e9er des badges se gagnant sur un crit\u00e8re du style &#8216;\u00eatre venu un certain nombre de fois sur une URL.&#8217; Donc mettre en place des d\u00e9corateurs sur des vues. Mais l\u00e0 encore, je ne voulais pas avoir \u00e0 cr\u00e9er des vues dans mon application rien que pour les tests.<\/li>\n<\/ul>\n<p>Au final, en lisant un peu de doc, j&#8217;ai r\u00e9ussi \u00e0 faire ce que je voulais.<\/p>\n<h2>\nTester un d\u00e9corateur sans cr\u00e9er des\u00a0 vues inutiles dans son app.<\/h2>\n<p>Je savais d\u00e9j\u00e0 comment forger des requests avec la <a href=\"https:\/\/docs.djangoproject.com\/fr\/1.5\/topics\/testing\/advanced\/#django.test.client.RequestFactory\" target=\"_blank\">RequestFactory<\/a>. Par contre pour cr\u00e9er des vues, je n&#8217;en avais pas la moindre id\u00e9e.. Une petite question plus tard, <a href=\"https:\/\/twitter.com\/foxmask\" target=\"_blank\">Foxmask<\/a> m&#8217;a indiqu\u00e9 un lien qui allait me donner la solution que je cherchais. (<a href=\"http:\/\/tech.novapost.fr\/django-testing-view-decorators-en.html\" target=\"_blank\">le voici<\/a>) Il suffisait au final d&#8217;utiliser mock pour cr\u00e9er, directement dans mes tests, une fausse vue que j&#8217;allais pouvoir d\u00e9corer.<br \/>\nUne derni\u00e8re subtilit\u00e9, comme vous le verrez dans le lien novapost (ou dans <a href=\"https:\/\/github.com\/mrjmad\/django_badgificator\/blob\/master\/badgificator\/decorators.py\" target=\"_blank\">mon code<\/a>), si vous utilisez wraps pour cr\u00e9er votre d\u00e9corateur, il faudra ajouter l&#8217;argument assigned=available_attrs(view_func) \u00e0 votre appel \u00e0 wraps (tout comme django le fait). Cela sera n\u00e9cessaire pour pouvoir utiliser votre d\u00e9corateur en mode fonction, ce que vous devrez faire dans vos tests, \u00e0 cause d&#8217;un bug python 2 (celui-ci\u00a0:<a href=\"http:\/\/bugs.python.org\/issue3445\" target=\"_blank\">http:\/\/bugs.python.org\/issue3445<\/a>)<\/p>\n<h2>\nCr\u00e9er des models uniquement pour les tests<\/h2>\n<p>Ici apr\u00e8s quelques test infructueux, je suis finalement tomb\u00e9 sur ce <a href=\"https:\/\/code.djangoproject.com\/ticket\/7835\" target=\"_blank\">ticket dans le track django<\/a>. Dont le dernier commentaire remont\u00e9 \u00e0 2 mois. Et en fait, l&#8217;astuce est toute simple. Il suffit de cr\u00e9er le model de test dans le fichier de test qui va bien (c&#8217;est <a href=\"https:\/\/github.com\/mrjmad\/django_badgificator\/blob\/master\/badgificator\/tests\/utils_for_tests.py\" target=\"_blank\">ici<\/a> au niveau de mon code) et ensuite de modifier manuellement une des migrations django pour ajouter la cr\u00e9ation du mod\u00e8le, uniquement si on est dans le mode Test. Petite modification de mon cru compar\u00e9 au code donn\u00e9 dans le ticket, j&#8217;ai fait en sorte que les models de tests soit cr\u00e9\u00e9 si la base commence par test ou si elle est stock\u00e9e en m\u00e9moire (mon <a href=\"https:\/\/github.com\/mrjmad\/django_badgificator\/blob\/master\/badgificator\/migrations\/0001_initial.py\" target=\"_blank\">code est ici<\/a>).<\/p>\n<p>Rien de bien merveilleux ou de bien r\u00e9volutionnaire, mais bon, on ne sait jamais, \u00e7a pourrait peut-\u00eatre \u00eatre utile \u00e0 l&#8217;un d&#8217;entre vous.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Je me suis enfin lanc\u00e9 dans l&#8217;\u00e9criture d&#8217;une app django g\u00e9rant les badges (ou les succ\u00e8s si vous pr\u00e9f\u00e9rez). L&#8217;objectif \u00e9tant de pouvoir r\u00e9\u00e9crire de z\u00e9ro histoires de r\u00f4listes. L&#8217;id\u00e9e \u00e9tait de tenter de faire une vraie app django, en mode r\u00e9utilisable, histoire que peut-\u00eatre des gens puissent trouver int\u00e9ressant de l&#8217;utiliser. Je me suis &hellip; <a href=\"https:\/\/j-mad.com\/blog\/2014\/11\/02\/django-1-7-et-ecriture-de-tests-petites-explorations\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Django 1.7 et \u00e9criture de tests, petites explorations<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[6],"tags":[],"class_list":["post-2587","post","type-post","status-publish","format-standard","hentry","category-django"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p12cdp-FJ","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/2587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/comments?post=2587"}],"version-history":[{"count":1,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/2587\/revisions"}],"predecessor-version":[{"id":2588,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/2587\/revisions\/2588"}],"wp:attachment":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/media?parent=2587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/categories?post=2587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/tags?post=2587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}