The Habit of TDD

An Aristotelian approach to trying out test-driven development

Miguel Bastos
xgeeks
6 min readMay 4, 2022

--

Raphael, School of Athens, fresco, 1509–1511

If you know about TDD you can jump introductions 😉

What is Test-driven development (TDD)?

TDD is first of all a technique or practice for software development that postulates writing an automated test before any production code. There is a cycle of writing a failing test, writing the minimal code to pass the test, and then refactoring. This cycle is known as the red-green-refactor.

red-green-refactor cycle

Red

Create a failing test, and figure out what is needed, and what is not needed. We can lay out the requirements, and think if they make sense. We start to have a better understanding of the code we want to write and how we can approach it.

Green

Only implement a minimal code that makes the failing test pass.

Refactor

Where the design happens (Khalil, Solid book, 28 Test-Driven Development Workflow). We are in greenfield, we can move code around, remove duplicates, rename variables, split functions and so on. But we should not add new functionalities.

Common objections

1 — Writing tests slows down the development process!

Writing tests may be slow in the beginning, but as soon as we start adding features to the codebase, tests will save us time because the feedback will increase our confidence.

2 — Writing tests first is not a good approach!

By starting with tests we are designing upfront, focusing on the requirements and the user point of view. We also get fast feedback, instead of changing the code, running the application, printing logs, debugging the code and staying awake all night, we can write the tests and let the tests speak.

3 — TDD provides no value!

Testing upfront will let us measure progress, understand requirements, and it will work as documentation for other developers. By creating a habit of writing tests we are adding a layer of security to the application.

Practical example

We can approach some stories by first writing an acceptance test that will fail, but we don’t care, what matters is that the test covers the scenario. Then we write unit tests applying the red-green-refactor cycle. When our acceptance test passes we know our job is done. This style of TDD is called Outside-in. The other well-known style is the Inside-out which can be used if there is already a good understanding of what to do.

Outside-in

Example code in GitHub

TDD and Habit

Aristotle defines five intellectual virtues (technê, epistêmê, phronêsis, sophia, and nous), two of them are commonly called practical virtues, art (technê) and prudence or practical wisdom (phronêsis). Art can also mean craft or skill and these terms will be used interchangeably throughout the article.

Virtues arise from habit, defined as a disposition to do well or act well. To achieve some good, we must conform to a habit that we will repeat until it becomes second nature.

Habits are needed to increase technical skills but also to sharpen moral virtues, needed for goodwill which comes from moral virtues to produce good crafts (Aquinas, Summa Q57 a. 3, ad 2).

Virtue can also improve the so-called soft skills and some other relevant virtues to us as software developers are justice => gratitude and giving each his due (delivery of good software); prudence (phronesis) => testing and good choices; fortitude => persevering.

But in this article let’s focus only on the practical side of things, techne and phronesis. To become better craftsmen we can’t just repeat until it works, blindfolded, like washing teeth kind of action. In a craft that requires learning, we first need to understand what is the right thing to do (prudence), know the principles (wisdom), and then do it repeatedly (goodwill), on top of good foundations.

After we are very good at some skill, the routine will not be the driving force at play for us, but rather, thoughtful actions that will improve our work day after day. And this will give us the capacity to explain and teach to others because it’s not just routine but reason, intelligent acts at play.

Pen sharpener

To sharpen our art we need to practice it, let’s read Aristotle (Nicomachean Ethics, Book II):

We learn an art or craft by doing the things that we shall have to do when we have learnt it: for instance, men become builders by building houses, harpers by playing on the harp. Similarly we become just by doing just acts, temperate by doing temperate acts, brave by doing brave acts.

In our craft, we build software, and quality software needs good test coverage, should enable other developers to have confidence in adding features, and should be simple to understand and discuss.

As software developers what we aim for is good software that not only works, but that is maintainable, flexible and testable (Khalil, Solid book, Part I: Up to Speed). And the big question is: How can we achieve this every time, as a kind of second nature? Where can we find some kind of habit we can stick to that will help us deliver good results repeatedly? We need a fixed and stable disposition, gained by practice, for building good software.

TDD is one of those practices, a good practice, some set of routines that will help us build software that fulfils its purpose, and its goal (telos). If the art we do (software development) completely fulfils its purpose (good software) we have achieved mastery in software development.

Master and apprentice

But don’t get me wrong, we don’t get good software by simply doing TDD, it’s not that simple, but for sure we are near to fulfilling the software development purpose.

If we divide software development into low level and high level, being the low level the clean code, clean architecture and the high level the business processes and definition of bounded contexts, TDD helps with the first and that’s not something small.

What we will get from perfecting the art of TDD is good design, understanding of the requirements, test coverage, and efficiency as feedback will increase speed and safety.

We can exercise our ideas and see how they work. We can test design patterns, rules and principles. We can also be happier, shut down the computer with a clean conscience and sleep better at night 😇 knowing we did a good job and that we tried our best to safeguard our own inevitable ever-present ⚠️ mistakes.

📚 Further reading on TDD, the philosophy of virtues and practical skills:

Kent Beck, Extreme Programming
Khalil Stemmler, Solid book
Aristotle, Nicomachean Ethics
Thomas Aquinas, Summa Theologica Q57
Julia Annas, Intelligent Virtue

If you enjoy working on large-scale projects with global impact and if you like a real challenge, feel free to reach out to us at xgeeks! We are growing our team and you might be the next one to join this group of talented people 😉

Check out our social media channels if you want to get a sneak peek of life at xgeeks! See you soon!

--

--