Skip to content

Commit bb02ad4

Browse files
committed
Apr 11 2025 - Test Driven Development by Kent Beck
1 parent 9a3503c commit bb02ad4

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: "Test Driven Development By Example by Kent Beck"
3+
date: 2025-04-11
4+
summary: The origin of TDD, an important software development practice that remains relevant and misunderstood even two decades later
5+
tags:
6+
- books
7+
- software design
8+
---
9+
10+
{%
11+
include progressive-image.html
12+
asset="tdd"
13+
path="books"
14+
alt_text="Test Driven Development By Example"
15+
%}
16+
17+
Few books have shaped modern software development as profoundly as Kent Beck’s _Test-Driven Development By Example_. Published in 2002, it introduced the simple yet disruptive idea of writing tests before writing code, a practice that has influenced how developers think about design, feedback, and programming discipline.
18+
19+
> “TDD is an awareness of the gap between _decision_ and _feedback_ during programming, and techniques to control that gap.”
20+
21+
## The Procedure Defined
22+
23+
Beck defines the "canonical" TDD process as follows:
24+
25+
1. **List the test scenarios**: Enumerate known behaviors or requirements the code must handle
26+
27+
2. **Write one test**: Start small by writing a test for a single scenario
28+
29+
3. **Make it (and all previous tests) pass**: Implement the minimal code necessary to satisfy the test
30+
31+
4. **Refactor if desired**: Once the test passes, refine the code’s design and structure without altering its behavior
32+
33+
5. **Repeat until there are no further tests to write**: Continue this cycle until all aspects of the desired functionality have been implemented
34+
35+
This iterative process fosters continuous feedback, encourages working in manageable increments, and ensures that each small change is reliable.
36+
37+
> “Testing is a process of learning, learning about the behavior of the system, learning about its weaknesses.”
38+
39+
## Why It’s Worth Doing
40+
41+
### Prevent Defects Early
42+
43+
By writing tests before code, TDD dramatically shortens the time between the introduction of a defect and its detection. The cycle shortens from days or weeks to mere seconds. This rapid feedback loop allows developers to catch and address issues immediately, ensuring that their changes are reliable.
44+
45+
> “Rather than apply minutes of suspect reasoning, we can just ask the computer by making the change and running the tests.”
46+
47+
### Improve Your Design
48+
49+
While TDD is not a replacement for making design decisions, it gives you immediate feedback about what is likely to be a _bad_ design. When tests are hard to write, slow to run, or non-deterministic, they serve as a warning sign that the underlying design may need rethinking. By paying attention to these signals, developers gain a valuable tool for making more thoughtful design choices.
50+
51+
> “Our guesses about the right interface are no more likely to be perfect than our guesses about the right implementation.”
52+
53+
### Reduce Regressions and Improve Collaboration
54+
55+
A robust test suite does more than verify current functionality -- it acts as a living document that captures the design rationale and assumptions behind the code. This documentation becomes invaluable for future programmers, reducing the risk of unintended regressions as the codebase evolves.
56+
57+
> “TDD allows developers to have courage; courage to modify, to delete, and to add.”
58+
59+
### Develop Faster
60+
61+
While writing tests may initially seem to slow down development, the long-term efficiency gains are significant. Developers waste less time debugging defects, chasing down regressions, wrestling with over-engineered solutions, or reworking poor designs.
62+
63+
### Reduce Anxiety and Increase Confidence
64+
65+
TDD has the ability to transform uncertainty into confidence. When faced with a challenging or ambiguous requirement, writing a test forces clarity. It turns vague concerns into concrete, manageable tasks. As each test passes, it reinforces trust in the codebase and builds momentum.
66+
67+
> “Write tests until fear is transformed into boredom.”
68+
69+
## Qualities of a Good Test
70+
71+
### Readable
72+
73+
A test should clearly express its intent, serving not only as a verification tool but also as a form of documentation. When a test is understandable at a glance, it communicates the original design rationale and guides future modifications.
74+
75+
### Fast and Automated
76+
77+
Tests must execute quickly and without human intervention. Fast tests encourage developers to run the entire suite frequently; Slow tests disincentivize the developer from integrating testing deeply into the development process.
78+
79+
### Isolated and Deterministic
80+
81+
Good tests are _isolated_, meaning they yield the same results regardless of the order in which they run. This ensures that each test is proving a specific piece of functionality without interference from others. Additionally, tests must be _deterministic_. If nothing changes in the code, the test result must remain consistent. Predictability is key to identifying genuine issues.
82+
83+
### Structure Insensitive
84+
85+
Tests should be sensitive to changes to _what the code does_ rather than _how it does it_. By disregarding implementation details, the internal structure is allowed to evolve.
86+
87+
### Confidence Inspiring
88+
89+
Each passing test should build confidence in the reliabiltiy of the software and the overall design. Each failing test should be specific enough to enable a deveoper to pinpoint the exact nature and location of the problem.
90+
91+
> “Each test should make a unique contribution, otherwise, it's just wasted, confusing execution time.”
92+
93+
### Understood Holistically
94+
95+
When new developers begin writing tests, a common mistake is to test _too much_. Consider a developer attempting to prove that a method truncates an input string to three characters. It would be impossible to test every possible combination of characters as inputs.
96+
97+
Instead, a better approach would be to test a few representative inputs:
98+
- A string with fewer than three characters
99+
- A string with exactly three characters
100+
- A string with more than three characters
101+
102+
By considering the tests together, we can _infer_ that the software actually works. This is a concept that Beck refers to as _composability_.
103+
104+
> “The confidence provided by one test should combine with the confidence provided by other tests.”
105+
106+
## Qualities of a Good Test Writer
107+
108+
While its easy to begin writing tests, it can take a life time to truly master the skill. Beck offers some insight into the qualities that embody a proficient test writer:
109+
110+
### Mastery of Small Steps
111+
112+
Good test writers know how to break complex problems into small, deliberate steps. It requires great skill to identify the smallest unit of behavior that can be implemented and verified independently. This practice, known as [behavioral composition](https://tidyfirst.substack.com/p/tdds-missing-skill-behavioral-composition), enables developers to incrementally build a system while ensuring each change is safe and well-understood.
113+
114+
> “The difference between a journeyman programmer and a master, from my perspective, is that the master never tries to eat the whole salami at once.”
115+
116+
### Flexibility in Approach
117+
118+
Experienced developers understand that the order of implementation can vary based on the problem at hand. Sometimes you implement the output code first. Other times you implement the input code first. Creative sequencing allows test writers to navigate complex problems more effectively.
119+
120+
> “Are the teeny-tiny steps feeling restrictive? Take bigger steps. Are you feeling a little unsure? Take smaller steps. TDD is a steering process -- a little this way, a little that way.”
121+
122+
## Objections to Adoption
123+
124+
Despite its many advantages, TDD has faced its share of resistance within the developer community. Beck himself acknowledges that TDD isn’t the right tool for every situation, but it’s worth asking whether every type of resistance is justified.
125+
126+
If you're uncertain about adopting TDD, consider whether any of the following might be influencing your hesitation:
127+
128+
### Fear of Responsibility
129+
130+
TDD requires developers to take full ownership of the code they produce. For some, this responsibility can feel daunting; every failing test is a stark reminder of the imperfections in one’s code. The idea of being accountable for every line of code, with immediate evidence of any mistake, can be intimidating.
131+
132+
> “If you're happy slamming some code together that more or less works and you're happy never looking at the result again, TDD is not for you.”
133+
134+
### Skill Issues
135+
136+
Effective TDD demands strong design intuition and the ability to decompose complex behaviors into smaller, testable units. Not all developers have honed these skills, and without them, TDD can seem cumbersome and impractical. For these individuals, practicing TDD would likely help them improve.
137+
138+
### Perceptions of "Rockstar Developers"
139+
140+
In a culture that often glorifies the image of the solitary, genius hacker writing perfect code in isolation, TDD might appear unglamorous. The methodical, iterative nature of TDD stands in stark contrast to the myth of the “flawless” programmer, leading some to dismiss it as a tedious chore rather than a valuable tool.
141+
142+
## One Tool, Among Many
143+
144+
Ultimately, it’s important to recognize that TDD is not a one-size-fits-all solution. While it offers significant benefits in terms of defect prevention, design feedback, and developer confidence, it is just one approach to achieving code quality.
145+
146+
The decision to adopt TDD should be based on a careful assessment of a team’s skills, project requirements, and overall workflow. As Kent Beck himself notes in various interviews and writings, the goal is always to produce code that others can rely on.
147+
148+
> “Am I recommending that you work this way? No. I'm recommending that you be able to work this way.”
149+
150+
## Conclusion
151+
152+
Kent Beck’s Test Driven Development is much more than a testing strategy. It’s a philosophy that encourages responsibility, fosters better design, transforms uncertainty into confidence, and leaves a legacy of clear documenation. When a team embraces TDD, it benefits every engineer who works on the code in the future. If you’re looking to elevate your development practices and build software that stands the test of time, this book is an essential read. Happy testing!
177 KB
Binary file not shown.
1000 KB
Loading
140 KB
Loading

0 commit comments

Comments
 (0)