Lets Unit Test Django Forms

Photo by Hitesh Choudhary on Unsplash

In the last few months I have been building a web application using Django. In a brief, It’s a app that does CRUD operations to a PostgreSQL DB. The project can be said to be moderate in size, it has dozens of models, dozens of views and a few dozen forms.

There was a moment when I was thinking that the project will grow more. If I make a change in a model, I will have to change its instances in different parts of the code like in views, Admins and forms.

Any tiny change could trigger a bug in the whole project. So I started researching about what good practices, libraries or approaches that I could implement to improve the development of my Django Application. I came up with Unit Testing and Test-Driven Development.

Test-Driven Development is a software development approach where you first write tests before making the logic of your application source code. This tests are write in form unit tests (testing every aspect of the code).

Unit Testing Django Forms

Forms are components that accepts data from the user. Django validates those forms based in the structure of the model that they are based on or the validations that you implement.

So, Let’s create our first unit testing for a form based in a a model. First lets create a project:

django-admin startproject unit-test-project
python manage.py startapp product
python manage.py runserver
python manage.py migrate

Making tests

In order to implement unit tests in your Django project, we can inherent our tests from TestCase. This is a subclass of unitest.TestCase, which is a class used in python for unit tests. There are other classes like TransactionTestCase or SimpleTestCase.

For make tests, we implement asserts. Assert are declarations that validates if a piece of code works correctly. There are multiple types of asserts like:

self.assertTrue // checks if a value is true
self.assertFalse //check if a value if false
self.assertEqual //check if two values are equal

If you want to learn more about them here is a link for a list of available asserts in python

Inside tests.py, write

from django.test import TestCase
from .models import Product
from .forms import ProductForm
class ProductFormTest(TestCase):def test_is_invalid(self):
form = ProductForm(data={"name": "Computer", "price": 400.1234})
def test_form_is_valid(self):
form = ProductForm(data={"name": "Computer", "price": 400})

We are going to validate if the data passed to the form is valid.

For run our tests, we have to run:

python manage.py test

This will search tests in any file named “test*.py” under the current working directory. This will cause an error because we don’t have our Product Model or Product Form.

Implementing model and form

In product’s model.py, write the next model:

class Product(models.Model):
name = models.CharField(max_length=25)
price = models.IntegerField()
def __str__(self):
return self.name

then hit

python manage.py makemigrations
python manage.py migrate

This will create the entity in the DB.

Now, write the next form in forms.py

from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ("name", "price", )

Having the model and the form, we can make the tests.

python manage.py test

This will show if the tests passed.


Make unit tests to every aspect of your code allows you to check if it works like you are expecting. You can use your tests as a documentation for your code. If you migrate the version of your library or programming language, it allows you to verify if everything is working correctly.

if you want to learn more about testing in Django: here and here are good links from Django documentation




Self-taught developer, mistake's seeker who loves to read about new technologies, science and learn about different fields.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Unit Testing in Java

SaaS Functionality Gaps? Try Our Genie.

Developing and deployment web services in Weblogic 14c

Introducing ARRAYS in PHP

How to play with WebGPU — low level GPU on the web

Deploy a secured Azure Container Instance with Traefik, Terraform and Let’s Encrypt

Some thoughts on running successful teams at Google

Amazon Seller Analytics: Products, Competitors & Fees

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Cristhian Ferreira

Cristhian Ferreira

Self-taught developer, mistake's seeker who loves to read about new technologies, science and learn about different fields.

More from Medium

JSONField Schema Validation in Django Rest Framework using Insomnia

Handle MEDIA files in production — Django

floppy disks and Django media

Creating a simple tic-tac-toe game with Django / Channels / DRF / Celery and Typescript.

[Django][Restframework] Filter data in Django Rest Framework