How to start using TDD cycle in your daily work and why it is worth it

Every person that has been interested in TDD for a while, should learn the term of TDD cycle/mantra (know also as red-green-refactor) which is the most important thing in TDD.

According to Kent Beck’s book Test-Driven Development By Example, this process includes three steps:

Write a test which describes result we want to achieve and run it to prove that the actual version of the application doesn’t include that feature – RED (test fails)

Try to make to test pass as soon as possible – GREEN (test passes)

Remove duplication – BLUE (code refactoring)

In the next paragraphs, I’m going to describe the goal of each of the above steps and the benefits of using this technique. On the last section, I would like to convince you that adopting TDD cycle in your daily work is not hard 🙂

Write test

In his book, Beck strongly recommends running tests after we wrote it even if we know that some error occurred because we don’t create class/module/file or implementation of the feature. Benefits of running a test at this moment are:

Making sure (but not guarantee) that the implementation is correct.

The failed test gives us confirmation that feature we want to implement doesn’t exist in a system.

The fulfilled test (change status color from Red to Green) gives us the feeling that we achieved our goal and also increased our trust to them.

There is only one case worse than project without test – a project with the test that we can’t trust.

Implement

In this step, we are focusing to change color from Red to Green. We shouldn’t think about anything else and try to achieve the pass test with every possible solution.

Based on our experience and knowledge about business rules of apps, we can achieve it in many ways. The easiest way to achieve Green color is to hardcode expected value to go swiftly to Refactor part. The most common way of achieving this step is to write code that makes this and every previous test to pass. If a developer feels comfortable with the code and business logic, he can start with obvious implementation and then add test for edge cases of the feature.

Remove duplication

Many people think that in this step they should refactor code to improve its quality, what is true (this is one of the main reason to create test – to be able to safely experiment with code to create better implementation) but first, we should focus on removing common code fragments from test and production code.

In the case of a strong connection between test and code, it is impossible to refactor only test or code (we should modify only one part of our app at a time). A classical example is mathematic operations:

function itsNotSimpleAddFunction(a,b){ return 5; } test("itsNotSimpleAddFunction", () => { expect(itsNotSimpleAddFunction(2,3)).toEqual(5); )); 1 2 3 4 5 6 function itsNotSimpleAddFunction ( a , b ) { return 5 ; } test ( "itsNotSimpleAddFunction" , ( ) = > { expect ( itsNotSimpleAddFunction ( 2 , 3 ) ) . toEqual ( 5 ) ; ) ) ;

Just after the first iteration of the TDD cycle, we should remove duplicated value 5 that appears both in code and test (and no change from 5 to 2+3 is not removing duplication ;)) If we try to extend or modify the code we will break test so we can’t move forward.

After we eliminate duplication, we are allowed to start refactoring in the classical meaning of this word.

Benefits of using TDD cycle

The first advantage of using this technique by the software developer is courage in interaction with code (understood as changes inside the code or refactor it).

The second one is the fact that we can treat the test as documentation of Interaction between features and their expected behavior.

Another benefit is active support for reaching the project’s goal by defining rigid procedures in each development step. This approach guarantees that a created code will implement functionality defined by tests. It’s crucial from a Product Owner’s perspective.

Despite the rigid process this technique is very flexible inside step: It doesn’t define the granularity of test or moment when we should finish refactor – this is decision is made by the developer based on his knowledge of the business domain, language, etc.

Even Kent Beck in his book a few times broke consciously breaks the rules to give to understand readers that TDD cycle should support the developer in his work not impose rigid rules of behavior in each step.

More details about the benefits of using TDD cycle, you can in Test-Driven Development By Example by Kent Beck.

It’s easy to start

Starting using the TDD cycle in daily work should be easy. If we look at a typical way of how developers are working on a feature, we will notice many common points:

Reading about requirements that need to be implemented

A basic implementation that is not perfect

If our implementation is correct, we do manual tests

Code refactoring

Writing tests / more manual test

Further refactoring and testing



So if we know what we need to do (after reading specification/ talking to Product Owner), wasting time on manual tests can be utilized to writing automated tests which make the most boring part of coding for us. What is more, many times developers realize that they can improve a part of code by adding something new or fixing what they have written, etc.

Adopting the TDD cycle to the development process can help you to remove this pain on the implementation step because it clearly defines a goal that a developer needs to achieve on each step.

The agenda of the article series “6 Misconceptions about TDD” is the following: