Squeaky clean code is critical to success
Ron Jeffries, https://ronjeffries.com/articles/017-08ff/clean-code/
Before we start our journey into the demanding and rewarding real of test-driven development, we need to ensure we have a working development environment. This chapter is all about preparing and setting things up.
Regardless of which reading pathway you follow (see figure 0.2), a clean development environment is indispensible to following this book. The rest of the book assumes that you have set up the development environment as described in this section.
Create a folder that will be the root for all the source code we’ll write in this book. Name it something that will be clear and unambiguous to you weeks from now, e.g. tdd-project.
Under this folder, create a set of folders as shown as follows:
tdd-project ├── go ├── js └── py
Create all these folders before you write the first line of code, even if you’re planning to follow this book in multiple passes, one language at a time. Creating this folder structure provides the following benefits:
It keeps code in the three languages separate yet in close proximity to each other.
It ensures that most commands in this book will work without changes. ..Commands that deal with fully qualified file/folder names are an exception — and such commands are rare. One of them is in this section.
It allows easy adoption of advanced features, such as continuous integration, across all three languages.
It matches the folder structure in the accompanying code repository. This can be useful for comparing and contrasting your code as it evolves.
Throughout the rest of this book, the term TDD Project Root is used to refer to the root folder containing all the source code — named
tdd-project above. The folders named
py are referred to by these very names — the meaning is clear from the context.
TDD Project Root is the name used to refer to the folder containing all the source code developed in this book. It’s the parent of three folders named
Declare an environment variable named
TDD_PROJECT_ROOT and set its value to the fully qualified name of the TDD Project Root folder. Doing this once in each shell (or better yet, once in your shell initialization script such as the
.bashrc file) ensures that all subsequent commands work seamlessly.
For example: on my macOS system, the fully qualified path for the TDD_PROJECT_ROOT is
We’ll need a text editor to edit source files. An Integrated Development Environment (IDE) can help by providing a single tool within which we can edit, compile, and test code in multiple languages. However, this is a matter of choice and personal preference; choose what works best for you.
Appendix A describes IDEs in more detail.
We’ll need a a shell — a command-line interpreter — to run our tests, examine the output, and for other tasks. Like IDEs, shell choices are many and often the subject of exuberant opinion-sharing amongst developers. This books assumes a bash like shell for the commands that need to be typed. On most — if not all — Unix-like Operating Systems (and on macOS), a bash shell is readily available.
For Windows, shells like Git BASH are available. On Windows 10, the Windows Subsystem for Linux provides native support for the bash shell, amongst many other “Linux goodies”. Either of these options, or something similar, is sufficient (and necessary) to follow the code examples in this book.
Figure I-1 shows a bash like shell with a the results of a command typed in it.
Chapter 13 introduces the practice of Continuous Integration using GitHub Actions. To follow the content of that chapter, we need to create a GitHub project of our own and push code to it.
Git is open-source distributed version control system. GitHub is an collaborative Internet hosting platform that allows people to preserve and share the source code of their projects with each other.
To ensure we can adopt Continuous Integration, we’ll do some preparation now and defer some work until Chapter 13. Specifically: we’ll set up the Git version control system on our development environment. We’ll postpone the creation of a GitHub project until Chapter 13.
First, download and install the Git version-control system. It is available for macOS, Windows and Linux/Unix. After you install it, verify that it works by typing
git --version on a terminal window and hitting enter. You should see the installed version of Git in response, as shown in figure I-2.
Next, we’ll create a new Git project in our TDD_PROJECT_ROOT. In a shell window, type the following commands.
$TDD_PROJECT_ROOTgit init .
This should produce an output saying
Initialized empty Git repository in _/your/fully/qualified/project/path/_.git/. This creates a shiny new (and currently empty) Git repository in our TDD_PROJECT_ROOT. We should have these folders under our $TDD-PROJECT-ROOT folder now:
tdd-project ├── .git ├── go ├── js └── py
.git folder is used by Git for bookkeeping. There is no need to make any changes to its contents.
As we write source code in the following chapters, we will periodically commit our changes to this Git repository. We’ll use the command line interface of Git to do this.
We’ll frequently commit our code changes to the Git repository in the rest of this book. To highlight this, we’ll use the Git icon.
We need to install Go version 1.16 to follow this book. This version is available to download for different operating systems.
To verify that Go is correctly installed, type
go on a shell and hit enter. There should be a rather long message, starting with a description of what Go is. See figure I-3.
We also need to set a couple of Go-specific environment variables:
GO111MODULE environment variable should be set to
GOPATH environment variable should not include the
TDD_PROJECT_ROOT or any folder under in, such as the
Execute these two lines of code in the shell:
We need to create a bare-bones
go.mod file to get ready to write code. These are the commands to do it:
$TDD_PROJECT_ROOT/go go mod init tdd
This will create a file named
go.mod whose contents should be as shown below.
For all Go development from this point on, make sure that the shell is in the
For the Go code in this book, make sure to first
cd $TDD_PROJECT_ROOT/go before running any Go commands.
Go’s package management is in the midst of a seismic shift. The old style — which used the
GOPATH environment variable — is being phased out in favor of the newer style using a
go.mod file. The two styles are largely incompatible with each other.
The two environment variables we defined above and the bare-bones
go.mod file we generated ensure that the Go tools can work correctly with our source code, especially when we create packages. We’ll create Go packages in Chapter 5.
We need Node.js v14 (“Fermium”) or v16 to follow this book. Both these versions are available from the Node.js website for different operating systems.
To verify that Node.js is correctly installed, type
node -v on a shell and hit enter. It should print a one-line message, listing the version of Node.js. See figure I-4.
assert NPM package for assertions and a simple class with methods to organize the tests. The simplicity is to keep our focus on the practice and semantics of TDD instead of the syntax of any one library. Chapter 6 describes the organization of tests in more detail. Appendix B enumerates the testing frameworks and the detailed reasons for not using any of them.
We need Python 3.9 to follow this book, which is available from the Python website for different operating systems.
The Python language underwent significant changes between “Python 2” and “Python 3”. While an older version of Python 3 (e.g. 3.6) may also work; any version of Python 2 will be inadequate for the purpose of following this book.
It is possible that you have Python 2 already installed on your computer. For example, many macOS operating systems (including Big Sur) come bundled with Python 2. It is not necessary (nor recommended) to uninstall Python 2 to follow this book; however, it is necessary to ensure that Python 3 is the version that’s used.
To prevent ambiguity, this book uses
python3 explicitly as the name of the executable in commands. It is possible — although also unnecessary — to “alias” the
python command to refer to Python 3.
Here’s a simple way to find out which command you need to type to ensure that Python 3 is used. Type
python --version on a shell and hit enter. If you get something starting with
Python 3, you’re in good shape. If you get something like
Python 2, you may need to explicitly type in
python3 for all the commands in this book.
Figure I-5 shows a development environment with both Python 2 and Python 3.
Use Python 3 to follow the code in this book. Do not use Python 2 — it won’t work.
Figure I-6 shows a mnemonic to simplify the preceding Python version rigmarole!
In this preliminary chapter, we got acquainted with the tool-chain we’ll need to start writing our code in a test-driven fashion. We also learned how to prepare our development environment and to verify that it is in working condition.
Now that we know what this book is about, what’s in it, how to read it, and most importantly: how to set up our working environment to follow it; we are ready to solve our problem, chiseling one feature at time, driven forward by tests. We’ll commence that journey in Chapter 1.