Test driven development with Pytest and Django

Kakar Nyori
4 min readAug 2, 2021

--

In this part, we will create our Task app and continue with Test-driven development we started previously on Test driven development with Pytest, Django and Docker — Set up.

The app

Let’s create the app

python manage.py startapp tasks

To include the app in our project, we need to add a reference to its configuration class in the INSTALLED_APPS setting:

INSTALLED_APPS = [
...
...
'tasks.apps.TasksConfig',
]

Delete the test.py file from the task app. Instead, create a new directory called tests/ inside the task app, and create an __init__.py file for it to be a python package.

We will be creating new test files (inside the task’s tests/ directory) for each file that we are going to test with Pytest. For example, for models.py we will create test_models.py.

And since we are following Test Driven Development, we will create our tests first.

The models

Create a tasks/tests/test_models.py and add the following

import pytest
from mixer.backend.django import mixer
@pytest.mark.django_db
class TestTask:
def test_model(self):
obj = mixer.blend('tasks.Task')
assert obj.pk == 1, 'Should create a task instance'

Run pytest and you can expect similar resuls:

We got our first Red!

Remember TDD is all about Red — Green — Refactor cycle:

  • Red: Write test cases first and check the Errors
  • Green: Solve the error
  • Refactor: If need be then refactor the code

Now that we got our error, it is telling us there is no Task class in our tasks app. Let’s create our Task model.

Update tasks/models.py with the following:

from django.db import modelsclass Task(models.Model):
title = models.CharField(max_length=100)
is_completed = models.BooleanField(default=False)

Now run the test again and you can expect similar results:

Our task model will also have an excerpt method for its title, and so it will return the first few characters from the title. So let’s first update our test for that.

Update tasks/tests/test_models.py

import pytest
from mixer.backend.django import mixer
@pytest.mark.django_db
class TestTask:
def test_model(self):
obj = mixer.blend('tasks.Task')
assert obj.pk == 1, 'Should create a task instance'
def test_excerpt(self):
obj = mixer.blend('tasks.Task', title='Buy milk from the market')
result = obj.get_excerpt(8)
assert result == 'Buy milk', 'Should return first few characters'

Run the test and you can expect similar results:

Since we don’t have a get_excerpt method, the error is telling us about that.

Let’s update our tasks/models.py to have our green!

from django.db import modelsclass Task(models.Model):
title = models.CharField(max_length=100)
is_completed = models.BooleanField(default=False)
def get_excerpt(self, total_char):
return self.title[:total_char]

Run the test again to check if the test has passed.

The admin

As we did with testing our models, we will create our tests first for the admin.py as well.

Create a tasks/tests/test_admin.py file and add the following:

from .. import models
from .. import admin
from django.contrib.admin.sites import AdminSite
import pytest
from mixer.backend.django import mixer
@pytest.mark.django_db
class TestTaskAdmin:
def test_excerpt(self):
site = AdminSite()
task_admin = admin.TaskAdmin(models.Task, site)
obj = mixer.blend('tasks.Task', title='Buy milk from the market')
result = task_admin.excerpt(obj)
assert result == 'Buy milk', 'Should return first few characters'

Run the test and you can expect similar output:

Since there is no TaskAdmin in our admin.py, we will need to write that out. Update task/admin.py with the following:

from django.contrib import admin
from . import models
class TaskAdmin(admin.ModelAdmin):
model = models.Task
list_display = ('excerpt',)
def excerpt(self, obj):
return obj.get_excerpt(8)
admin.site.register(models.Task, TaskAdmin)

Run the test again, and you can expect similar output:

Yay! Now that, most of the app is tested. We will see how to follow test driven development with the views.py and Django rest framework in the next part.

If you want, you can check out the repo.

See you soon!

--

--

Kakar Nyori
Kakar Nyori

No responses yet