Chapter 0: Introduction and Setup

Squeaky clean code is critical to success.

Ron Jeffries, “Clean Code: A Learning,” Aug 23, 2017, ronjeffries.com

Before we start our journey into the demanding and rewarding world of test-driven development, we need to ensure we have a working development environment. This chapter is all about preparing and setting things up.

Setting Up Your Development Environment

Regardless of which reading pathway you follow (see Figure P-2), you need a clean development environment to follow this book. The rest of the book assumes that you have set up the development environment as described in this section.

Important

Regardless of which of Go, JavaScript, or Python you start with, set up your development environment as described in this section.

Common Setup

Folder structure

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 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:

  1. It keeps code in the three languages separate yet in close proximity to each other.

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

  3. It allows easy adoption of advanced features, such as continuous integration, across all three languages.

  4. 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 go, js, and py are referred to by these very names—the meaning is clear from the context.

Important

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 go, js, and py.

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.

export TDD_PROJECT_ROOT=/fully/qualified/path/to/tdd-project

For example, on my macOS system, the fully qualified path for the TDD_PROJECT_ROOT is /Users/saleemsiddiqui/code/github/saleem/tdd-project.

Text editor or IDE

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.

Shell

We’ll need a shell—a command-line interpreter—to run our tests, examine the output, and carry out other tasks. Like IDEs, shell choices are many and often the subject of exuberant opinion sharing among developers. This book 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, among many other “Linux goodies.” Either of these options, or something similar, is sufficient (and necessary) to follow the code examples in this book.

Figure 0-1 shows a Bash-like shell with the results of a command typed in it.

An iTerm shell on a macOS operating system
Figure 0-1. A Bash-like shell, like the one shown here, is needed to follow the coding examples in this book

Git

Chapter 13 introduces the practice of continuous integration (CI) 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 an open source distributed version control system. GitHub is a collaborative internet hosting platform that allows people to preserve and share the source code of their projects with each other.

Important

Git is a free, open source, distributed version control system. GitHub is a code-sharing platform that uses Git.

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 0-2.

Verify that Git is installed on a shell
Figure 0-2. Verify that Git is installed by typing git --version and hitting Enter on a shell

Next, we’ll create a new Git project in our TDD_PROJECT_ROOT. In a shell window, type the following commands:

cd $TDD_PROJECT_ROOT
git 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

The .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 Git CLI (command line interface) to do this.

Important

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 Git icon.

Go

We need to install Go version 1.17 to follow this book. This version is available to download for different operating systems.

To verify that Go is correctly installed, type go version on a shell and hit Enter. This should print the version number of your Go installation. See Figure 0-3.

Verify that Go is working on a shell
Figure 0-3. Verify that Go is working by typing go version and hitting Enter on a shell

We also need to set a couple of Go-specific environment variables:

  1. The GO111MODULE environment variable should be set to on.

  2. The GOPATH environment variable should not include the TDD_PROJECT_ROOT or any folder under in, such as the go folder.

Execute these two lines of code in the shell:

export GO111MODULE="on"
export GOPATH=""

We need to create a bare-bones go.mod file to get ready to write code. These are the commands to do it:

cd $TDD_PROJECT_ROOT/go
go mod init tdd

This will create a file named go.mod whose contents should be:

module tdd

go 1.17

For all Go development from this point on, make sure that the shell is in the go folder under TDD_PROJECT_ROOT.

Important

For the Go code in this book, make sure to first enter cd $TDD_PROJECT_ROOT/go before running any Go commands.

A quick word on Go package management

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.

JavaScript

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. The command should print a one-line message, listing the version of Node.js. See Figure 0-4.

Verify that Node.js is working on a shell
Figure 0-4. Verify that Node.js is working by typing node -v and hitting Enter on a shell

A quick word on testing libraries

There are several unit-testing frameworks in the Node.js ecosystem. By and large, they are excellent for writing tests and doing TDD. However, this book eschews all of them. Its code uses the 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.

Another quick word, on JavaScript package management

Similar to testing frameworks, JavaScript has many ways to define packages and dependencies. This book uses the CommonJS style. In Chapter 6, there is a discussion of the other styles: the ES6 and UMD styles are shown in detail with source code, and the AMD style more briefly, without source code.

Python

We need Python 3.10 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 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 (or 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 0-5 shows a development environment with both Python 2 and Python 3.

Verify that Python 3 is working on a shell
Figure 0-5. Verify that Python 3 is installed and the command you need to type to use it (python3 as shown here)
Important

Use Python 3 to follow the code in this book. Do not use Python 2—it won’t work.

Figure 0-6 shows a mnemonic to simplify the preceding Python version rigmarole!

For all the Python code in this book, remember this easy and cheesy rhyme! Python 2: boo! Python 3: glee!
Figure 0-6. Simple mnemonic to clarify which version of Python is needed for this book!

Where We Are

In this preliminary chapter, we got acquainted with the toolchain 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. Let’s roll!

Get Learning Test-Driven Development now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.