Skip to content

Commit dc19908

Browse files
committed
update root README and the ones in cs and java.
1 parent 2f12123 commit dc19908

3 files changed

Lines changed: 212 additions & 46 deletions

File tree

README.md

Lines changed: 123 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,150 @@
1-
# Test Driven Development Example Code
1+
# "Test-Driven Development: By Example" Code Samples
22

3-
Back in 2004, I was working for a company that had one of the most extensive test suites I have ever seen (to this day).
3+
In 2002, Kent Beck published his seminal book on Test-Driven Development (TDD),
4+
["Test Driven Development: By Example"](https://a.co/d/5tOeg2z). I call it "The TDD Bible." It is still one of the best
5+
books on TDD and I highly recommend it to anyone interested in learning more about TDD.
6+
7+
The book did not come with a code sample repository, so I decided to create this repository to share the example code
8+
that Kent used in the book in both Java and C#. At some point, I may add Python and/or React versions as well.
9+
10+
The Java code is in the `java` folder and the C# code is in the `cs` folder. I have provided a README.md in each of those
11+
folders that provides details on how to setup your environment for that language.
12+
13+
Underneath each language folder are folders numbered `ch00` through `ch17`. Each folder has a README.md that provides
14+
information and editorial comments about that chapter. The `ch00` folder contains an empty project for its language that
15+
can be used as starting point if you want to follow along yourself, *which I highly recommend you do*.
16+
17+
## My Journey with TDD
18+
Back in 2004, I was working for a company ([Progress Software Corporation](https://www.progress.com/)) that had one of
19+
the most extensive test suites and some of the best engineering practices I have ever seen (to this day).
420
The majority of the codebase was written in C/C++ and even though we were using Rational Clearcase for version control,
521
we had a very strict build process that regression-tested all code during the nightly-build.
622

723
We started development on a new product that involved extensions to Eclipse and we were using Java. We took the
8-
opportunity to introduce some of the concepts of TDD into our development process, but we were not big proponents of
9-
building the tests first and then coding to make them succeed. We were a Rational Unified Process (RUP) shop and XP
10-
was still in its infancy.
24+
opportunity to introduce some of the concepts of TDD into our development process. We were looking for ways to make sure
25+
we applied the same level of rigor to our Java solutions as we did to our core code base. At the time, though, we were a
26+
Rational Unified Process (RUP) shop and XP was still in its infancy.
1127

1228
A few years later, I was working for a company that was embarking on its Agile journey and we embraced TDD as part of
13-
that process. Since then, I have been a strong advocate for TDD and I have seen the benefits it brings to software
14-
development.
29+
that process. As a result, I have been a strong advocate for TDD and I have seen the benefits it brings to software
30+
development for the last 21 years (yeah, it really is that long!).
1531

16-
In the last few months I have seen a lot of posts about TDD on social media that have made me reflect on my own
17-
experiences with it. I decided to go back to the
18-
TDD Bible - ["Test Driven Development: By Example" by Kent Beck](https://a.co/d/5tOeg2z) - and work through the examples again. It's been
19-
at least 17 years since I last did it, and I never kept the code from back then.
32+
## Why this Repository?
2033

21-
A quote from the book that really caught my attention was this:
34+
There's a quote in the book that really sums up why I created this repository:
2235
> You will often be implementing TDD in code that doesn't have adequate tests (at least for the next decade or so).
2336
> - Kent Beck, "Test Driven Development: By Example," Chapter 6, page 29, (c) 2003
2437
25-
The book was written in 2002. I have worked at several companies since then and I think it is true to say that many codebases
26-
still do not have adequate tests. In fact, I'd venture a guess that we have not made much progress in that area in the last 20
27-
years for existing codebases and, in all likelihood, have a lot more code that is not tested than code that is.
38+
The book was written in 2002.
39+
40+
Over the last few years, I have gone from working at companies that had a strong testing culture to companies that had
41+
little to no testing culture. It seems to be true that the further you drift from technology-focused companies, the less
42+
focus there is on testing. Kent Beck's own experience seems to confirm that as he joined Facebook 2011 and was surprised
43+
to find that they had very little automated testing.
2844

29-
I decided to work through the examples in the book again and create a repository to share the code with others who may
30-
want to do the same.
45+
It's this lack of a testing culture that led to this repository for a couple of reasons:
46+
1. I have taken on roles at several employers where I needed to establish a testing culture and I found
47+
myself going back to the TDD Bible to refresh my memory on the principles of TDD so I could point my teams at a code base
48+
that helps them ramp up.
49+
2. In the last few months I have seen a lot of argumentative posts about TDD on social media that have made me reflect on
50+
my own experiences with it. TDD has saved me on more than one occasion, so the social media arguments made me think that
51+
I should go back to the source and re-immerse myself in the principles of TDD.
52+
53+
That's what led to me going back to the TDD Bible again - ["Test Driven Development: By Example" by Kent Beck](https://a.co/d/5tOeg2z) -
54+
and working through the examples to create this repository. Although I have worked through the book several times,
55+
I never kept the code and this time I decided to work through the examples in the book again and create a repository
56+
to share the code with others who may want to do the same.
3157

3258
## References
33-
[Test Desiderata](https://kentbeck.github.io/TestDesiderata/)
59+
- [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+
3464

3565
## About this Repository
3666

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.
41109

42110
### Structure of the Repository
43111
- 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.
47119
- 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
50123
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).
52125
- Each chapter has its own folder with the corresponding code and a README.md specific to that chapter.
53126
- 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.
57129
- 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.
59130
- As the book is based on Java and JUnit, I had to take some liberties with the C# code because of the subtle
60131
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.
64132

65133
### 'ch17' folders
66134
Chapter 17 of the book is a retrospective on the Money example. In it, Kent suggests a refactor of the Expression
67135
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
69137
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
72141
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
74143
instead of integers. It also contains contains the CurrencyTransaction class that was modeled on the foreign wire
75144
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.
78148

79149
## Key Concepts from the Book
80150

@@ -93,6 +163,12 @@ The TDD cycle consists of five main steps:
93163
> Remember, TDD is not about taking teeny-tiny steps, it's about *being able* to take teeny-tiny steps.
94164
> - Kent Beck, "Test Driven Development: By Example", Chapter 1, page 9
95165
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+
96172
### Three strategies for getting to green
97173
1. **Fake it**: Return a constant and gradually replace it with variables until you have real code.
98174
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
104180
105181
Instead of spending 5 to 10 minutes reasoning out a problem, TDD gives you the ability to ask the computer to solve the
106182
problem in 15 seconds.
183+
107184
> Without the tests you have no choice, you have to reason. With the tests you can decide whether an experiment would
108185
> answer the question faster.
109186
110187
### 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
116193
have a red bar.
117194

118195
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

cs/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# "Test-Driven Development: By Example" in C#
2+
3+
This folder contains C# implementations of the examples from the book "Test-Driven Development: By Example" by Kent
4+
Beck. The examples cover various aspects of Test-Driven Development (TDD) and demonstrate how to apply TDD principles in
5+
C#.
6+
7+
## Contents
8+
I already described the contents of this repository in the [main README](../README.md#structure-of-the-repository), so
9+
please refer to that for more information about the examples included here.
10+
11+
## Getting Started
12+
I'm going to assume you have some familiarity with C# and .NET development and that you have a development environment
13+
(JetBrains Rider, Visual Studio, or VSCode) set up for C#.
14+
To get started with the examples in this repository, follow these steps:
15+
1. Install .NET SDK 8.0 or later: Make sure you have the .NET SDK installed on your machine. You can download it from
16+
the official [.NET website](https://dotnet.microsoft.com/download) or use a package manager like Homebrew (for MacOS) to
17+
install it.
18+
2. You will also want the .NET CLI tools for running tests and managing projects. These are included with the .NET SDK.
19+
3. Create a working directory for yourself and clone this repository to your local machine using Git:
20+
```bash
21+
git clone https://github.com/The-Software-Gorilla/tdd-by-example.git
22+
```
23+
This will pull down the entire repository, including the C# and Java examples.
24+
4. Navigate to the `cs` directory and one of the chapter directories to explore the code examples.
25+
5. Open the solution file (`.sln`) in your preferred C# IDE to explore the code and run the tests.
26+
6. You can run the tests using your IDE's built-in test runner or by using the .NET CLI. To run the tests from the
27+
command line, navigate to the test project directory and execute:
28+
```bash
29+
dotnet test
30+
```
31+
7. In Rider, you can also right-click on the `Money.Tests` project and select "Run Unit Tests" to execute the tests.
32+
33+
## Code Structure
34+
The C# examples are organized into separate directories, each corresponding to a chapter or section of the book. Each
35+
directory contains a C# solution file (`.sln`). You can open these solution files in your preferred C# IDE (like
36+
JetBrains Rider, Visual Studio, or VSCode) to explore the code and run the tests.
37+
38+
The code is in two separate projects within each solution:
39+
- `Money`: The main project contains the implementation code.
40+
- `Money.Tests`: The test project contains the unit tests for the implementation code.

0 commit comments

Comments
 (0)