🧠 What Is Test-Driven Development (TDD)?
Test-Driven Development (TDD) is a software development approach where you write tests before writing the actual code.
It follows a simple but powerful three-step cycle:
Red – Write a test that fails.
Green – Write the minimal code needed to make the test pass.
Refactor – Clean up the code while keeping all tests passing.
This process ensures your code:
Does exactly what it should.
Is easier to maintain.
Is covered by tests from day one.
⚙️ TDD Workflow Overview
Here’s the TDD cycle illustrated:
[Write Failing Test] → [Run Tests: Fails 🔴]
↓
[Write Minimal Code]
↓
[Run Tests: Pass ✅] → [Refactor Code] → Repeat
🧩 Example: TDD in a Django Project
Let’s build a small Django feature using TDD —
for example, a To-Do app where users can create simple tasks.
🧱 Step 1: Write a Failing Test (RED)
Before writing any model or view, we start with a test that defines the behavior we want.
Create a test file tests/test_models.py:
from django.test import TestCase
from myapp.models import Task
class TaskModelTest(TestCase):
def test_saving_and_retrieving_tasks(self):
first_task = Task(title='Buy groceries')
first_task.save()
saved_tasks = Task.objects.all()
self.assertEqual(saved_tasks.count(), 1)
self.assertEqual(saved_tasks[0].title, 'Buy groceries')
Now run the test:
python manage.py test
❌ Output:
ImportError: cannot import name 'Task' from 'myapp.models'
Perfect — it fails because we haven’t created the Task model yet.
This is the RED stage.
🧩 Step 2: Write the Minimal Code (GREEN)
Now, let’s make the test pass by creating the minimal model.
models.py
from django.db import models
class Task(models.Model):
title = models.CharField(max_length=200)
Run tests again:
python manage.py test
✅ Output:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
The test passes!
We’re now in the GREEN stage.
🧩 Step 3: Refactor (REFACTOR)
At this stage, we can clean up or improve the code — for example, add __str__ or validations — without changing functionality.
class Task(models.Model):
title = models.CharField(max_length=200)
def __str__(self):
return self.title
Re-run the tests to ensure nothing broke:
python manage.py test
✅ Still green — great!
That’s the REFACTOR stage.
🧩 Extending TDD to Views
Let’s now add a simple view that displays the list of tasks.
Step 1: Write a Failing Test (RED)
from django.test import TestCase
from django.urls import reverse
from myapp.models import Task
class TaskViewTest(TestCase):
def test_displays_all_tasks(self):
Task.objects.create(title='Task 1')
Task.objects.create(title='Task 2')
response = self.client.get(reverse('task_list'))
self.assertContains(response, 'Task 1')
self.assertContains(response, 'Task 2')
Run it:
python manage.py test
❌ It fails because the task_list view and URL don’t exist yet.
Step 2: Write Minimal Code (GREEN)
views.py
from django.shortcuts import render
from myapp.models import Task
def task_list(request):
tasks = Task.objects.all()
return render(request, 'task_list.html', {'tasks': tasks})
urls.py
from django.urls import path
from myapp import views
urlpatterns = [
path('', views.task_list, name='task_list'),
]
Template: templates/task_list.html
<ul>
{% for task in tasks %}
<li>{{ task.title }}</li>
{% endfor %}
</ul>
Run tests again:
python manage.py test
✅ All tests pass — you’ve implemented your feature completely through TDD!
🧩 Step 3: Refactor
Once all tests pass, you can safely improve your code:
Simplify queries.
Extract reusable components.
Improve templates.
Re-run tests to ensure everything still passes.
🧠 Benefits of TDD in Django
Benefit Description
Confidence Every feature is verified automatically.
Fewer bugs You catch mistakes before they reach production.
Cleaner design Forces you to think about what code should do before writing it.
Easy refactoring Safe to improve code since tests confirm correctness.
⚙️ Tools That Help with TDD
Django Test Client – simulates HTTP requests.
pytest-django – integrates Django with the simpler pytest framework.
coverage.py – checks how much of your code is tested.
Example:
coverage run manage.py test
coverage report -m
🧭 Summary: The TDD Cycle in Django
Step Action Goal
1. RED Write a failing test Define the expected behavior
2. GREEN Write minimal code to pass Implement the functionality
3. REFACTOR Clean and improve code Maintain readability and efficiency
Learn Fullstack Python Training in Hyderabad
Read More
Writing Unit Tests for Django Projects
Introduction to Unit Testing in Python
Testing and Debugging in Python
How to Test Your API Endpoints in Python
At Our Quality Thought Training Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments