Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test custom Django forms clean/save methods?

Most of the time I have to change/extend the default form save/clean methods. However I'm not really sure how to test the custom save/clean methods.

Most of the time my tests are like:

response = self.client.post(reverse('example:view_name'), kwargs={'example, self.example'})
self.assertEqual(200, response.status_code)
self.assertTemplateUsed('example.html', response)

Using self.client.post from Django's TestCase class, to capture the response isn't enough and definitely doesn't cover/test custom save and clean.

What's your practice of testing forms? In my opinion what I did above is wrong, since it's more of an integration test that goes through the view to get to the form.

like image 683
Anton Antonov Avatar asked Sep 19 '14 15:09

Anton Antonov


People also ask

How do I check if a form is valid in Django?

The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.

What is clean in Django forms?

The clean() method on a Field subclass is responsible for running to_python() , validate() , and run_validators() in the correct order and propagating their errors. If, at any time, any of the methods raise ValidationError , the validation stops and that error is raised.

How do you validate a form in Python?

You can use is_valid() when required to validate complete form-data. This validation will check for Python-datatypes. This function will return True or False (Python Data Types) in return.

What does form Save Do Django?

form. save() purpose is to save related model to database, you are right. You're also right about set_password , for more info just read the docs. Django knows about model and all it's data, due to instance it's holding (in your case user ).


1 Answers

Create the form directly in the tests, and call is_valid method (clean is called by is_valid); check whether it validate correctly. Same for the save method.

For example:

from django.contrib.auth.forms import (UserCreationForm, ...)

...

class UserCreationFormTest(TestCase):

    def test_user_already_exists(self):
        data = {
            'username': 'testclient',
            'password1': 'test123',
            'password2': 'test123',
        }
        form = UserCreationForm(data)
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form["username"].errors,
            [force_text(User._meta.get_field('username').error_messages['unique'])])

(Above code came from the django source code - django/contrib/auth/tests/test_forms.py).


BTW, the parameters for assertTemplateUsed are response, template_name, ..., not template_name, response, .....

The last line in the code in the question should be:

self.assertTemplateUsed(response, 'example.html')
like image 65
falsetru Avatar answered Sep 24 '22 07:09

falsetru