{"id":410,"date":"2012-10-30T14:33:34","date_gmt":"2012-10-30T18:33:34","guid":{"rendered":"http:\/\/dashdrum.com\/blog\/?p=410"},"modified":"2012-10-31T08:55:25","modified_gmt":"2012-10-31T12:55:25","slug":"unit-testing-forms-in-django","status":"publish","type":"post","link":"https:\/\/dashdrum.com\/blog\/2012\/10\/unit-testing-forms-in-django\/","title":{"rendered":"Unit Testing Forms in Django"},"content":{"rendered":"<p>This is a subject that doesn&#8217;t seem to be covered well by other sources, so I am recording my notes on testing a Django form. Credit to &#8220;fRui Apps&#8221; for <a href=\"http:\/\/blog.fruiapps.com\/2012\/10\/Easier-Testing-of-django-models-and-forms\">this post<\/a> that gives an example. (See the section <strong>Testing Forms<\/strong>)<\/p>\n<p>My goal is to get the test as close to the code as possible. Rather than using the view test, or even Selenium, this approach will isolate the form&#8217;s functions without going through all of Django&#8217;s URL routing, middleware, etc. Save that for the functional tests.<\/p>\n<p>In this first example, my form will pad the entered number with left hand zeroes. This is the quick test:<\/p>\n<pre><code>def test_id_format(self):  \n    ## Use factoryboy to create a model instance  \n    e = EndowmentFactory.create()\n    ## Instantiate form  \n    form = EndowmentEntityForm(data={'endowment': e.pk,  \n                                     'id_number': '528989',  \n                                     'entity_type': EntityType.ORIGINATOR,})\n    ## call is_valid() to create cleaned_data  \n    self.assertTrue(form.is_valid())  \n    ## Test away!  \n    self.assertEqual(form.clean_id_number(),'0000528989')\n<\/code><\/pre>\n<p>Note that I&#8217;m using <a href=\"https:\/\/factoryboy.readthedocs.org\/en\/latest\/\">factoryboy<\/a> to create a model instance to work with. The form data includes an id_number of fewer than 10 characters. After I call <code>is_valid()<\/code> to populate <code>cleaned_data<\/code>, I can test the cleaned id_number for the proper format.<\/p>\n<p>In this next example, I am testing for valid and invalid data. My application allows changing the status of an object, but certain rules apply. Here is a test confirming that a valid change is allowed to continue:<\/p>\n<pre><code>##  Test for valid action types\ndef test_action_type_valid(self):\n    ## Use factoryboy to create a model instance\n    e = EndowmentFactory.create(status='E')        \n    ## Instantiate form\n    form = UserActionForm(data={'endowment': e.pk,\n                                'username': 'dgentry',\n                                'action_type': 'A',})\n    ## is_valid() should return True if no errors are found\n    self.assertTrue(form.is_valid())\n<\/code><\/pre>\n<p>And this will test for an invalid status change:<\/p>\n<pre><code>##  Test for valid action types\ndef test_action_type_valid(self):\n    ## Use factoryboy to create a model instance\n    e = EndowmentFactory.create(status='A')        \n    ## Instantiate form\n    form = UserActionForm(data={'endowment': e.pk,\n                                'username': 'dgentry',\n                                'action_type': 'E',})\n    ## We run is_valid() and expect False\n    self.failIf(form.is_valid())\n    ## check for the error\n    self.assertIn(u'Invalid Action',form.errors['__all__'])\n<\/code><\/pre>\n<p>I&#8217;m sure that I will learn more about testing forms as I go. Stay tuned&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a subject that doesn&#8217;t seem to be covered well by other sources, so I am recording my notes on testing a Django form. Credit to &#8220;fRui Apps&#8221; for this post that gives an example. (See the section Testing Forms) My goal is to get the test as close to the code as possible. &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/dashdrum.com\/blog\/2012\/10\/unit-testing-forms-in-django\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Unit Testing Forms in Django&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-410","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/comments?post=410"}],"version-history":[{"count":5,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/410\/revisions"}],"predecessor-version":[{"id":415,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/410\/revisions\/415"}],"wp:attachment":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/media?parent=410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/categories?post=410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/tags?post=410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}