Home » Good Practices » What TDD is? How I’m using it?

What TDD is? How I’m using it?

Every experienced developer knows how important is to cover your code with tests (or at least business logic). However, not everyone likes to do that once code is already written, because, why should we do that? The work is done, it was tested and it functions correctly, right?

I never liked to cover the code with tests once it’s already there. That’s why in this article I’ll present Test Driven Development and describe how I use it day to day.

What TDD is?

Test Driven Development (TDD) is a programming technique where a developer, before even writing the business logic, creates unit tests which fulfills some part of requirements. It’s important to write only a small part, not everything at once! Below you might see the TDD’s development cycle:

Test Driven Development Cycle
Test Driven Development Cycle

Thanks to this technique, our code, not only is covered with unit tests but it makes us think about the design before we even begin writing anything. Hopefully, we won’t create any useless code and waste our time, instead we will think about code design, design patterns and most important, what exactly is required to fulfill the requirements. I would like to add how easy it is to follow SOLID principles once we’re using TDD (I’ll describe what SOLID in incoming articles).

How to start with TDD?

It looks easy on the picture, right? Unfortunately, like most techniques in programming, it’s not that straightforward. When I started my journey with it, I had no idea how to start testing business logic without any implementation. I had many question, i.e. when to finish unit tests (red cycle) and start filling them with implementation code (green cycle).

In theory it is:

  1. Create minimal number of tests (in most cases one) for the first part of business logic, i.e. service constructor where later you’ll pass a parameter (assuming you know what you want to pass). Now you could assume if there’s no parameter, you should throw an exception. In this example, you should have one test with one line of code (NUnit implementation):
    [TestFixture]
    public class MyServiceTests
    {
        [Test]
        public void Given_NullAsCtorParameter_When_CreatingNewObject_Then_ItShouldThrowAnException()
        {
            Assert.That(() => new TestService(null), Throws.TypeOf<ArgumentNullException>());
        }
    }
  2. Write the code which will make your unit test to pass:
    public class TestService
    {
        public TestService(string testParameter)
        {
            if (string.IsNullOrEmpty(testParameter))
            {
                throw new ArgumentNullException(nameof(testParameter));
            }
        }
    }
  3. Try to refactor the code making sure all unit tests will pass. In this example there’s nothing to refactor which means you should continue.

Next, repeat these steps until you fulfill business logic i.e. create, using unit tests, what should happen inside of your service and what is expected as an output of this service and then implement that inside of this service. Remember to do it slowly, in steps and stick into TDD cycle.

How I use TDD?

I’ve read a lot of articles and watched many courses (mainly Pluralsight) about TDD and unit testing. All of them were useful. Thanks to them I found the way how I would like to follow these rules.

Following my experience, I know, that business doesn’t like and wouldn’t like to know that we, developers need more time to finish our work because of test cycles. That’s why I’m following my three rules of good Test Driven Development.

My Tools

To fully use the power which TDD gives, we should focus on how existing tools will help us faster and better writing unit tests. Tools, which I am using, of course, in addition to Visual Studio, are:

  • Resharper – productivity extension every .NET developer should know and use. It automates most of what can be automated in your coding routines, show compiler errors, code errors, etc… I don’t want to get into details here, because Resharper should be well known to all. If it’s not, please visit JetBrains Resharper page for more info.
  • NCrunch – is an automated concurrent testing tool for Visual Studio. It intelligently runs automated tests so that you don’t have to, and gives you a huge amount of useful information about your tested code, such as code coverage and performance metrics, inline in your IDE while you type. One of the cons I found with Ncrunch is that you need to have powerful PC to use it efficiently.

    NCrunch example
    NCrunch example. Check the green dots on the left side. It’s awesome!

My Frameworks

Nuget packages which I’m using with TDD are:

  • NUnit – .NET testing framework. You may use anything from MSTests, XUnit or any other.
  • Moq – package to mock interfaces, objects etc… Helps with injecting dependencies what I’m doing everyday.
  • AutoFixture – open source library which helps with “Arrange” section of your tests in order to maximize maintainability. Its goal is to allow developers to focus on what is being tested rather than to setup the test scenario. I found it very useful, maybe someone else will use it as well.

My Technique

In theory, we should be writing one unit test in one cycle. That’s what I was doing for long time, however, with experience I found a better way of doing this (at least it works for me). Usually, when I was writing one test scenario, my brain was thinking about next one. That’s why I found a better way to do it by, instead of writing one unit test and one functionality, write several of them which will fulfill more requirements and finish red-green-refactor cycle. Bear in mind to do it slowly and to not exceed limited time, in my case it’s 10 minutes. I found this technique works better for me. I’m not spending too much time on one test where I could be writing more.

Summary

In my opinion, TDD is helpful not only when you’re writing unit testable code. In many occasions, I was creating integration tests first i.e. when working with AWS/database/microservices. When I’m doing this, NCrunch is off. I don’t want to make it call AWS/database/microservices hundreds of times in a short period. TDD helps me plan my work and functionality beforehand.

I hope someone will find this article useful. For more details about TDD and unit testing, please check these Pluralsight courses:

Published by

Mateusz Pustelak

Software Developer with several years of commercial experience, TDD practitioner, DDD/CQRS fan. Currently working for Universal Music Group in London.

Leave a Reply

Your email address will not be published. Required fields are marked *

*