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.
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.
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.
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.
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 ).
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With