Skip to content
August 28, 2025

Growth with support: What test-driven development has to do with gardening

Custom Software
Product development

At first glance, software development and gardening have little in common. But just as plants need support to grow in a controlled manner, test-driven development helps to build code that is stable and reliable right from the start. We explain the method in a way that is easy to understand for developers and hobby gardeners alike.

Test-driven development has been around for a long time, but it is still not common practice in many projects. At makandra, however, some of our colleagues have firmly integrated this technique into their daily development routine and wouldn't want to be without it. But what exactly is it?

Our Principal Engineer Dominik Schöler explains test-driven development using an example that not only developers but also botanists (and hobby gardeners) can easily relate to. Because let's be honest: anyone who has ever planted a new plant knows the desire for it to grow exactly as they imagined. Many plants need a little support to do this: tomato plants and grapevines, for example, need to be staked so they can develop properly. It's very similar with code.

What is test-driven development?

Test-driven development is a methodology in which developers write the tests before the actual code.

This approach originated in the 1990s as an alternative to the rigid and slow development processes of the time. The approach is characterized by short development cycles, continuous feedback, and the goal of writing precise and stable code from the outset.

There are different variants of test-driven development: tests-first development, test-driven development, behavior-driven development, acceptance-driven development, and many more.

We will explain how test-driven development can be described in simple terms using a botanical metaphor.

Example: Test-driven development

Imagine your code is a plant: when developing new features, integration tests give the plant its external form. Like a support stake that sets the rough direction. This establishes the framework, and you can see at a glance where it should go (in this case, "upward").

However, this is often not enough, as the young plant may tend to tip over or sway within its framework.
This is where unit tests come into play: they function like small plant clips that hold the plant in place at specific points and thus clearly fix its behavior at individual points.

The right number of tests is a crucial consideration.

What happens if there are too many tests? The plant is like it's in concrete. Of course, its behavior is perfectly fixed, but any subsequent changes require laboriously breaking up the concrete again. And what if there are too few tests? The plant grows uncontrollably, and a branch may break off in a storm.

It is therefore important to fix the plant (the code) at the crucial points. This ensures that the plant develops as planned.

Our test-driven development process explained

Our test-driven development process follows a top-down approach, where tests serve as a planning aid or to-do list:

  1. Write down the feature
    First, write down all conceivable usage scenarios individually, without going into too much detail (i.e., in the simplest form possible). The goal is to cover all functionalities of the new feature (i.e., typical use cases, potential malfunctions, different access rights, special cases, etc.).
  2. Formulate scenarios
    Formulate the scenarios one after the other in detail, as long as it is clear how they will continue.
  3. Implement
    Proceed step by step and convert the previously developed scenarios into code one after the other. As soon as code is created that is not covered by an integration test (such as a single function, an auxiliary module, or a special edge case), a unit test should be written specifically for it.
  4. Write down unit behavior
    Consider all individual cases that could play a role in the new function (e.g., specific inputs, unusual values, error cases, or auxiliary functions in the background). Again, cover all important aspects, but this time at the level of individual building blocks, not complete processes.
  5. Formulate and implement unit tests
    Formulate one of the cases noted above. Then write just enough code to make this test run successfully (turn "green").

And yes, sometimes we come up with new test cases while we're doing this, in which case we just go back a step or two. Test-driven development is not a rigid recipe, but rather a living planting plan.

Why we at makandra rely on test-driven development

Test-driven development is not an end in itself for us. It helps us build applications that not only work, but are stable, maintainable, and reliable right from the start. Automated testing allows us to detect errors early on, secure existing functions, and integrate new features into the system safely.

This allows our projects to grow in a controlled but lively manner. Just like a well-tended plant.

Your idea deserves strong implementation
As an experienced development partner, we help you turn complex requirements into functioning software – pragmatically, reliably, and tailored precisely to your problem.
Your customized software