Test-Driven Development (TDD)
Test-Driven Development (TDD) is a software development approach where tests are written before the actual code. Developers first define the specifications or requirements of the feature as test cases and then write code to pass those tests.
Goal
The primary goal of TDD is to improve the design of features and write cleaner, more testable code. It aims to improve both the quality of the software and the productivity of developers by reducing debugging time and enhancing code clarity.
Context
There are infinite ways to write code like there are infinite ways to write a book. But not all ways are equal. We need code to be testable so that we can automate our validity checks. We need code to be maintainable so that we can continue to iterate on the code without slowing down through increasing technical debt. We need code to be reliable so that we can spend time building features instead of fixing bugs. TDD is a practice that helps us achieve these goals.
Types of TDD
Format | Description | Benefits | Considerations | Best Suited For |
---|---|---|---|---|
London School (Outside-In) | Starts with user interface (UI) or API interactions. Focuses on testing overall application behaviour from a user's perspective. |
|
|
|
Chicago School (Inside-Out) | Starts with domain logic and core functionalities. Focuses on testing the internal state and behaviour of individual classes. |
|
|
|
Red: Write a Failing Test Start by writing a test for the next bit of functionality you want to add. The test should fail because the functionality hasn't been implemented yet. This step ensures that the test is meaningful and that it accurately reflects the requirements of the functionality. | Green: Make the Test Pass Write just enough code to make the test pass. The aim here is to quickly get to a passing state, without worrying about perfection. This often means the code isn't the cleanest, but it meets the criteria defined by the test. | Refactor: Clean Up the Code Once the test is passing, look at the code you've written and consider how it can be improved without changing its functionality. This might involve removing duplication, improving names for clarity, or applying design patterns. The tests written in the Red stage ensure that this refactoring does not alter the behaviour of the code. | ||
Writing tests after: The benefits of TDD are not the tests themselves, but the process of writing the tests first which results in better designed and more maintainable code. | Overcomplicating tests: Tests that are too coupled to implementation are hard to maintain and become an impediment to change. Tests should be simple and focused on the behaviour of the system. | Not considering the readability of tests: Making it difficult for others to understand the test suite or the intent behind code changes. |