This is a short post regarding my use of TDD. I’m not gonna do a long post about the theory behind TDD and all the rules, because there are already hundreds (if not thousands) of those already. However, I am going to leave a couple of links at the bottom for those of you who want to read more about TDD.

Why do I use TDD?

Because it helps me verify that the code I’m writing is doing what I’m expecting it to do. It also allows me to refactor the code without being afraid that I might break something while doing so.

Example using existing code

public int Sum( int i, int j )
{
    return i * j;
}

The method Sum has a bug. It must have been created without the use of TDD. 😊
Let’s fix this.

We start by writing a test to help us verify the bug. In this example I’m using C# and xUnit.

[Fact]
public void Sum_ShouldReturnTheSumOfTwoIntegers()
{
    var integerOne = 1;
    var integerTwo = 2;
    var result = Sum( integerOne, integerTwo );
    Assert.Equal( 3, result );
}

The output from running the test clearly shows that the Sum method is not doing what we expect.

💥 Sum_ShouldReturnTheSumOfTwoIntegers
Assert.Equal() Failure
Expected: 3
Actual:   2

Alright!
Let’s fix the code and run the test again.

public int Sum( int i, int j )
{
    return i + j;
}
 Sum_ShouldReturnTheSumOfTwoIntegers 

This time the output shows no errors and the test is marked as green (successful).

Example building new code

We have been given a task to create a method that should return the word “Hello” followed by the text that the user has written.

Let’s start by writing a test with the expected behavior.

[Fact]
public void HelloThere_ShouldReturnHelloWithInput()
{
    var someInput = "Jack";
    var result = HelloThere( someInput );
    Assert.Equal( "Hello Jack!", result );
}

Run the test!

Of course the test failed because the method doesn’t exist yet.

The reason why we want a failing test to start with is because we want to make sure the code we are writing are actually fixing the test we created. If we were to add the code directly and then run the test we could end up with a successful test without it running the code we created. This example is very basic so it may not be obvious why this could happen, but in more complex solutions it is important to remember this.

Let’s create the missing method.

public string HelloThere( string input )
{
    return someInput;
}

Run the test again!

💥 HelloThere_ShouldReturnHelloWithInput
Assert.Equal() Failure
 (pos 0)
Expected: Hello Jack!
Actual:   Jack
 (pos 0)

A failing test! Awesome!

public string HelloThere( string input )
{
    return $"Hello {input}";
}

Quickly fixed!
Let’s run the test again.

💥 HelloThere_ShouldReturnHelloWithInput
Assert.Equal() Failure
 (pos 10)
Expected: Hello Jack!
Actual:   Hello Jack
 (pos 10)

What!? It failed again!? 😲
Oh yeah… I was so eager to write code that I forgot the exclamation mark…
Good thing we had a test. 😉

public string HelloThere( string input )
{
    return $"Hello {input}!";
}

Let’s run the test again!

 HelloThere_ShouldReturnHelloWithInput

And as a finishing touch we can refactor it.

public string HelloThere( string input ) => $"Hello {input}!";

Let’s run the test one last time to make sure we didn’t break anything.

 HelloThere_ShouldReturnHelloWithInput

Still successful!
Good job!

Check out the links below for more information regarding TDD.

TDD on Wikipedia
Test Driven Development (TDD): Example Walkthrough
Test-Driving the Game Loop pt. 1