Red-Green-Refactor: Mastering Test-Driven Development in Python
Overview of Test-Driven Development
(TDD) flips the traditional coding process on its head. Instead of building features and then checking for bugs, you write the test first. This forces you to define the requirements and interface of your code before a single line of implementation exists. Originally popularized by in his book , this methodology creates a safety net that ensures your code does exactly what it is supposed to do from the start.
Prerequisites
To follow this guide, you should have a solid grasp of basics, including classes and methods. Familiarity with basic math operations and a general understanding of how software modules interact is helpful.
Key Libraries & Tools
- : The built-in library for creating and running tests. It provides a framework for organizing test cases and making assertions.
- Standard Library: Used for basic data types like floats and integers, though decimals are often preferred for financial accuracy.
Code Walkthrough
The TDD cycle follows the Red-Green-Refactor pattern.
The Red Phase
First, we write a test for a method that doesn't exist yet. In our example, we want to compute an employee's payout. We create a test case that expects a specific float value.

import unittest
from employee import Employee
class TestEmployee(unittest.TestCase):
def setUp(self):
self.test_emp = Employee(name="Alice", pay_rate=100.0, hours_worked=10)
def test_payout_with_commission(self):
self.test_emp.contracts_landed = 10
# Expecting 1000 (base) + 1000 (commission) = 2000
self.assertAlmostEqual(self.test_emp.compute_payout(), 2000.0)
Running this now results in a failure (Red) because compute_payout is not implemented.
The Green Phase
Now, write the simplest possible code to make the test pass. Avoid over-engineering; just satisfy the assertion.
def compute_payout(self):
payout = self.pay_rate * self.hours_worked
if self.has_commission:
payout += self.commission_rate * self.contracts_landed
return payout
Running the tests again should yield a success (Green).
The Refactor Phase
With passing tests, you can safely clean up the code. You might split a generic employer_cost variable into specific categories like office_costs and 401k_costs. Because you have a test harness, you know immediately if your cleanup broke the logic.
Syntax Notes
- setUp: This method runs before every single test. Use it to create a fresh "test fixture" (like an instance) so tests stay isolated.
- assertAlmostEqual: Essential when comparing floats. It accounts for the tiny rounding errors inherent in floating-point math.
Practical Examples
TDD is vital in financial systems where calculating tax or payroll requires extreme precision. It is also excellent for API development, where defining the input and output (the interface) first prevents scope creep.
Tips & Gotchas
- Isolate Tests: Never use global instances. If Test A modifies an object that Test B relies on, you'll face nightmare debugging scenarios.
- Don't Test Built-ins: You don't need to test if can assign a variable. Focus on your custom logic.
- Use Fixed Values: Always compare your code's output against a hard-coded, known result rather than a copy of the logic inside the test file.
- 56%· programming languages
- 11%· people
- 11%· books
- 11%· software development
- 11%· libraries

Test-Driven Development In Python // The Power of Red-Green-Refactor
WatchArjanCodes // 15:10
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!