Let’s talk about Test-Driven Development

tddCoverPhoto

The following article introduces software development in line with the Test-Driven Development approach. TDD will be presented in theory, as well as in the example, which will allow for a faster understanding of the issue.

What is TDD?

TDD is a software development approach in which a developer starts by writing a test. The next step is to create a production code that passes the test. Finally, a refactoring phase appears, where the business logic and test code is ordered. The whole cycle is called intercom.

Testing the software proves the existence of bugs, not lack thereof.

– Author unknown
tddScheme
Phases in TDD

TDD in practice

Let’s say you create an online store. The user who would like to use it would need to register in advance and activate the account by confirming the email address. Here’s what the next steps would look like if you used the TDD approach.

Note! In the article I will use matchers of the Hamcrest library.

Let’s start by creating a test class and the first method to verify that the newly created account is not active:

class AccountTest {

    @Test
    void newlyCreatedAccountShouldNotBeActive() {

        given
        Account account = new Account();
    }
}

The test becomes red because the Account class is missing. So we move on to its creation. It is worth mentioning that we only create an Account class, because this is the minimum amount of code needed to pass the test. We run the test and manage to pass it. We check if there is a possibility of refactoring. If not , we return to further expansion of the test:

    @Test
    void newlyCreatedAccountShouldNotBeActive() {

        given
        Account account = new Account();

        then
        assertThat(account.isActive(), equalTo(false));
    }

The test is red again due to the lack of implementation of the isActive() method. So let’s move on to its creation:

public class Account {

    public boolean isActive() {
        return true;
    }
}

The test will compile, although it will be red. Therefore, you must add logic to the Account class so that the test succeeds:

public class Account {

    private boolean active;

    public Account() {
        this.active = false;
    }

    public boolean isActive() {
        return this.active;
    }
}

The test result is positive. You can end another cycle because refactoring is not needed again. We have finished creating the first test method and class based on the TDD approach.

So let’s create a second test class to see if your account is active after activation:

    @Test
    void accountShouldBeActiveAfterActivation() {
        
        given
        Account account = new Account();

        when
        account.activate();
    }

The test is red because the account class is missing the activate() method. So we only create a class signature so that the test passes. At the moment, you can be tempted by a little refactoring. Instead of creating new account class instances in each test, you can create it once as a test class field:

class AccountTest {

    Account account = new Account();

    @Test
    void newlyCreatedAccountShouldNotBeActive() {

        then
        assertThat(account.isActive(), equalTo(false));
    }

    @Test
    void accountShouldBeActiveAfterActivation() {

        when
        account.activate();
    }
}

We return to the further expansion of the test:

    @Test
    void accountShouldBeActiveAfterActivation() {

        when
        account.activate();

        then
        assertThat(account.isActive(), is(true));
    }

The test is red because the assertion is not met. We return to the Account class to add some logic to the activate() methods:

    public void activate() {
        this.active = true;
    }

The refactoring phase is omitted, so the second test can also be considered finished.

It is well aware that the example presented may seem trivial, although it is merely intended to focus on the course of the TDD proceedings.

A summary of the

At first glance, the use of TDD may seem unprofitable due to the increased effort, and therefore the time. However, there are a significant number of advantages that are rewarded by the effort put into writing the additional code, e.g.:

  • reduce the cost of catching an error due to its faster detection
  • application stability
  • more thoughtful code
  • faster implementation of changes

I hope that I was able to present what the TDD methodology is and how much value the software production based on it brings. It is important to make an informed decision to use TDD based on all factors before starting a project, without just looking at the extra time and cost spent writing the tests.

All the code from the entry is on my Githubie.

Leave a Comment

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