Overview of Test-Driven Development 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 Kent Beck in his book Test Driven Development by Example, 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 Python basics, including classes and methods. Familiarity with basic math operations and a general understanding of how software modules interact is helpful. Key Libraries & Tools * **unittest**: The built-in Python library for creating and running tests. It provides a framework for organizing test cases and making assertions. * **Python 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. ```python 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. ```python 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 Employee 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 1. **Isolate Tests**: Never use global instances. If Test A modifies an object that Test B relies on, you'll face nightmare debugging scenarios. 2. **Don't Test Built-ins**: You don't need to test if Python can assign a variable. Focus on your custom logic. 3. **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.
Test Driven Development by Example
Books
Aug 2021 • 1 videos
High activity month for Test Driven Development by Example. ArjanCodes among the most active voices, with 1 videos across 1 sources.
Aug 2021
- Aug 13, 2021