You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Test-Driven Development: By Example](https://a.co/d/5tOeg2z) - Book by Kent Beck
60
+
-[Is TDD Dead?](https://martinfowler.com/articles/is-tdd-dead/) - Conversation between Martin Fowler and Kent Beck
61
+
-[Test Desiderata](https://kentbeck.github.io/TestDesiderata/) - Kent Beck's website on testing
62
+
-[Software Design: Tidy First](https://tidyfirst.substack.com/) - Newsletter by Kent Beck
63
+
34
64
35
65
## About this Repository
36
66
37
-
The code in this repository is the example code that Kent Beck used in his book "Test Driven Development: By Example".
38
-
It demonstrates the principles of Test Driven Development (TDD) chapter by chapter according to the examples in the book.
39
-
I have created separate examples for each chapter and I have also provided code in Java and C#. I may add a Python
40
-
and/or React version later.
67
+
The repository contains the code samples from the book in both Java and C# and each chapter contains a complete working
68
+
example that you can run and test yourself that illustrates the code for that chapter.
69
+
70
+
### Code Maturity
71
+
The book was written in 2002 and the code examples were based on Java 1.3 or 1.4, and I'm not sure what version of JUnit
72
+
was in place at the time. Things like generics, lambdas, records, and streams did not exist yet, and
73
+
[fluent interfaces](https://martinfowler.com/bliki/FluentInterface.html) were not a thing back then. The code base
74
+
therefore intentionally limits the use of modern language features to stay true to the original code examples in the book.
75
+
That said, the concepts are still as relevant today as they were 20-some years ago.
76
+
77
+
### Development Environment
78
+
I use the [JetBrains suite of IDEs](https://www.jetbrains.com/all/) for all my professional development work, so I have
79
+
used [JetBrains Rider](https://www.jetbrains.com/rider/) for the C# code and
80
+
[IntelliJ IDEA Ultimate](https://www.jetbrains.com/idea/) for the Java code.
81
+
82
+
You can probably use Visual Studio or Visual Studio Code (VSCode) for the C# code and Eclipse or VSCode for the
83
+
Java code, but I have not tried that myself because I only work on MacOS, Eclipse is slow and resource-greedy, and
84
+
VSCode is not a commercial-quality IDE.
85
+
86
+
### The TODO List
87
+
Kent Beck uses a TODO list in the book to keep track of what needs to be done next. I have included the TODO list
88
+
in each chapter's README.md file in the state it is in at the end of that chapter.
89
+
90
+
I have also added the TODO list to the code itself as comments in the `DollarTest` class through Chapter 5 and then in
91
+
the `MoneyTest` class from Chapter 6. In chapter 12, Kent removes a whole bunch of TODO comments from the code, so I
92
+
moved the ones that were done into a DONE list in the code.
93
+
94
+
**Before you complain about TODO's in the code:** The book was written in 2002. I simply wanted to stay true to the
95
+
original code examples in the book, warts and all. ***I would never write production code and check it into `main` with
96
+
TODO comments in it.***
97
+
98
+
Rider and IntelliJ IDEA both have TODO support that picks up comments in the code that start with TODO, so you can easily
99
+
find the list of TODOs in a tool pane in the IDE itself. I know VSCode and Eclipse have similar support.
100
+
101
+
In the C# code, I have put the TODO comments in a `#region TODO List` block at the top of the `DollarTest` and `MoneyTest`
102
+
classes to make it easy to find and fold away. I know this works in Visual Studio and VSCode as well.
103
+
104
+
I did a similar thing in the Java code, where I put the TODO comments in a `//<editor-fold desc="TO DO List">`
105
+
block at the top of the `DollarTest` and `MoneyTest` so that you can easily find it and fold it away. I think this
106
+
might be a feature specific to IntelliJ IDEA, so it may not work in other IDEs. I had to label the tag for the `editor-fold`
107
+
as `TO DO List` instead of `TODO List` because otherwise IntelliJ IDEA would pick it up as a TODO comment that will show
108
+
up in the TODO pane.
41
109
42
110
### Structure of the Repository
43
111
- The money example spans 17 chapters and each language has complete example code for each complete chapter.
44
-
- The C# example is in the 'cs' folder. Development work was done using VSCode and C# 12, .NET 8 and dotnet CLI.
45
-
- The Java example is in the 'java' folder. Development work was done using IntelliJ IDEA, Java 23, JUnit 5 and
46
-
Maven 3.9.9.
112
+
- There is a [GitHub Actions CI/CD pipeline](./.github/workflows/tdd-by-example-tests.yml) that builds and tests
113
+
both the C# and Java code on every push and pull request.
114
+
- The C# examples are in the `cs` folder. Development work was done using JetBrains Rider and .NET 8.0.414, NUnit 4.4.0
115
+
and dotnet CLI.
116
+
- The Java example are in the `java` folder. Development work was done using IntelliJ IDEA, Java 24 and 25, JUnit 5.13.4
117
+
and Maven 3.9.11. Java 25 was used on my local machine, but GitHub Actions only supports up to Java 24 at the time of
118
+
writing, so the CI/CD pipeline uses Java 24. Note that I use Maven to build the Java code, not Gradle.
47
119
- Each language folder has a README.md that provides details on how to setup your environment for that language.
48
-
- Each language has folders numbered 'ch00' through 'ch17' and a 'money' folder.
49
-
- The 'ch00' folder contains an empty project for its language that can be used as starting point if you want to follow
120
+
- Each language has folders numbered `ch00` through `ch16` and then 4 `ch17` folders numbered `ch17-01` through
121
+
`ch17-04`.
122
+
- The `ch00` folder contains an empty project for its language that can be used as starting point if you want to follow
50
123
along yourself.
51
-
- The 'ch17' and 'money' folders contain code that is not in the book. See notes in the [next section](https://github.com/The-Software-Gorilla/tdd-examples#ch17-and-money-folders).
124
+
- The `ch17` folders contain code that is not in the book. See notes in the [next section](https://github.com/The-Software-Gorilla/tdd-examples#ch17-and-money-folders).
52
125
- Each chapter has its own folder with the corresponding code and a README.md specific to that chapter.
53
126
- The code is organized to follow the TDD cycle.
54
-
- I initially thought about creating a separate branch for each chapter, but I decided against it because:
55
-
- Branches cannot be constrained to a single folder, so I couldn't keep .NET code in one branch and Java in another
56
-
so the code is easy to navigate.
127
+
- I initially thought about creating a tag for each chapter, but I decided against it because:
128
+
- Tags cannot be constrained to a single folder, so I couldn't keep .NET and Java tags separated neatly.
57
129
- It would be difficult to see the progression of the code through the chapters.
58
-
- It would be difficult to see the differences between the Java and C# implementations.
59
130
- As the book is based on Java and JUnit, I had to take some liberties with the C# code because of the subtle
60
131
differences between C#, Java, NUnit and JUnit.
61
-
- Bear in mind the book was written in 2002, so the Java and JUnit versions it was based on did not have support for
62
-
lambdas, anonymous functions, etc. We're talking Java 1.4-ish. That said, the concepts are still as relevant today as
63
-
they were 20-some years ago.
64
132
65
133
### 'ch17' folders
66
134
Chapter 17 of the book is a retrospective on the Money example. In it, Kent suggests a refactor of the Expression
67
135
interface into a class. I decided to give that a try to see if I can resolve the "plus" duplication. He also suggested
68
-
a refactor of the unit tests to leverage fixtures. I took that on in the Chapter 17 code. There are therefore 4 distict
136
+
a refactor of the unit tests to leverage fixtures. I took that on in the Chapter 17 code. There are therefore 4 distinct
69
137
ch17 folders:
70
-
1.**ch17-01-tests:** This folder contains refactored unit tests that get to 100% code coverage.
71
-
2.**ch17-02-plus:** This folder contains the code after the refactor to fix the duplicae plus issue. There are
138
+
1.**`ch17-01-tests`:** This folder contains refactored unit tests that use fixtures and test cases and extend the tests
139
+
to get to 100% code coverage.
140
+
2.**`ch17-02-plus`:** This folder contains the code after the refactor to fix the duplicate plus issue. There are
72
141
significant changes in both Java and C# that made it possible to create very clean code that was not possible in 2002.
73
-
3.**ch17-03-decimal:** This folder contains the code after I refactored the Money object to return decimal values
142
+
3.**`ch17-03-decimal`:** This folder contains the code after I refactored the Money object to return decimal values
74
143
instead of integers. It also contains contains the CurrencyTransaction class that was modeled on the foreign wire
75
144
transfers that I do for family from time to time.
76
-
4.**ch17-04-arithmetic:** This folder extends the currency arithmetic to support subraction and division as well.
77
-
It also changed the addRate() method on the Bank class to enable reciprocal exchange rates.
145
+
4.**`ch17-04-arithmetic`:** This folder extends the currency arithmetic to support subtraction and division as well. It
146
+
uses operator overloading in C# to make the code more natural and it also changed the addRate() method on the Bank class
147
+
to enable reciprocal exchange rates.
78
148
79
149
## Key Concepts from the Book
80
150
@@ -93,6 +163,12 @@ The TDD cycle consists of five main steps:
93
163
> Remember, TDD is not about taking teeny-tiny steps, it's about *being able* to take teeny-tiny steps.
94
164
> - Kent Beck, "Test Driven Development: By Example", Chapter 1, page 9
95
165
166
+
### Red, Green, Refactor
167
+
The TDD cycle is often summarized as "Red, Green, Refactor":
168
+
1.**Red**: Write a failing test.
169
+
2.**Green**: Write just enough code to make the test pass.
170
+
3.**Refactor**: Remove duplication and improve the design.
171
+
96
172
### Three strategies for getting to green
97
173
1.**Fake it**: Return a constant and gradually replace it with variables until you have real code.
98
174
2.**Use Obvious Implementation**: Type in the real implementation.
@@ -104,15 +180,16 @@ Chapter 10, page 46, Kent talks about one of the major benefits of a base of cle
104
180
105
181
Instead of spending 5 to 10 minutes reasoning out a problem, TDD gives you the ability to ask the computer to solve the
106
182
problem in 15 seconds.
183
+
107
184
> Without the tests you have no choice, you have to reason. With the tests you can decide whether an experiment would
108
185
> answer the question faster.
109
186
110
187
### Code without a test
111
-
Chapter 10, page 47 has a paragraph that starts: "Whoa! Code without a test? Can you do that?" Kent then lays out three reasons
112
-
why it is OK under certain circumstances to write code without a test:
113
-
1. We're about to see the results of the test on the screen.
114
-
2. Because the toString() method is being used only for debug purposes, the risk of failure is low.
115
-
3. We're in the process of running tests and we have a red bar (test failure). We'd prefer not to write a test when we
188
+
Chapter 10, page 47 has a paragraph that starts: "Whoa! Code without a test? Can you do that?" Kent then lays out three
189
+
reasons why it is OK under certain circumstances to write code without a test:
190
+
> 1. We're about to see the results of the test on the screen.
191
+
> 2. Because the toString() method is being used only for debug purposes, the risk of failure is low.
192
+
> 3. We're in the process of running tests and we have a red bar (test failure). We'd prefer not to write a test when we
116
193
have a red bar.
117
194
118
195
Kent then goes on to point out later on the page that the conservative course is to back out a change to get back to
0 commit comments