Image of a plain as a blank canvas for our custom software development

Introduction to TDD

Arteco - Information Technologies

  • :)
  • :0
  • :D
  • ;)
  • :]
foto Ramón Arnau

Ramón Arnau

Gerente de Arteco Consulting SL

Test Driven Methodology (TDD) is a guide to Approaching Java Developments with Quality without losing focus on the objectives

Test Driven Development (TDD) programming has become one of the most desired skills in companies. It offers guarantees of operation, protects against failures during evolutions, and validates the correct application of components. Find out why using TDD is advisable.

What is TDD (Test Driven Development)

TDD stands for Test Driven Development, which corresponds to an approach to developing mobile applications or general programming of information systems. It is known as a development methodology and is based on defining user cases using the same programming language, which can be automatically executed to verify that the (not yet programmed) application supports all user requirements registered. The successful execution of all user cases determines the suitability of the implemented solution.

Therefore, it can be said that applying TDD is divided into two well-defined phases. The first one is to gather all the functionalities expected from the information system in the form of several (many) unit tests. Meanwhile, the second one aims to implement (program) the body of the application so that all tests are executed correctly. To carry out the second phase, all elements that will ultimately compose the application itself must be programmed.

Benefits of Using TDD in a Software Project

Test-driven programming covers two important aspects in software development. It allows to delimit the scope of a project, since all user requirements should be reflected in test cases. Many times, the enumeration of tests is considered part of the contract that the programming services provider must carry out. At the same time, it will be the proof of delivery of a project working correctly by the provider.

The successful execution of the cases validates the implementation and therefore the work done, as well as offering guarantees of correct operation during evolutions and error correction.

How to Implement the TDD Methodology

Practically all modern programming languages, together with the programming frameworks that accompany them, provide functionalities, either natively or through third-party libraries, to be able to automatically execute unit tests during the program construction phase. If any of the tests fail, the final binary is not built, showing the user which tests did not pass, either because an error occurred or because they returned an incorrect result.

It should be noted that applying TDD requires a very specific programming style, where programmers create functional units easy to invoke by a test. This requires that the program has a good component design and manages dependencies well between them. Since a test must have direct and simple access to the invocation of any functional unit, without having to instantiate hundreds of components to consume a particular method. So it is basic to perform a good decomposition of components and separation of responsibilities.

However, junior programmers often lack the overall vision and experience needed to create a good design of components that are easy to instantiate and use, and that only respond to a specific and reusable responsibility. It is with time or with the help of other senior programmers that they will reach the maturity necessary to apply TDD correctly. Still, it is advisable to introduce TDD in the initial stages of any software project and guide them through the process.

In the case of developing the application with Java, tests are written as classes and methods. The most common library for executing these classes in the form of tests is called jUnit, and the Maven build tool is responsible for automatically executing all classes marked as tests via jUnit.

Tests are considered source code of the project, and therefore must be part of the code under version control. So, if the Java source files are usually in src/main/java, the testing classes will be in src/test/java.

How to Write a Test in TDD

The answer depends on the programming language. But practically all of them follow the same pattern or pseudo-code where there are well-defined phases for each unit case. Its implementation may vary depending on the type of project where TDD is being implemented. In new projects it will be much easier to introduce than in those that already exist and are programmed without considering TDD, because in new projects it is usually easier to perform a good separation of components. Still, any test must have the following steps.

Phases of a unit test:

  1. Instantiation of the component. Tests are intended to verify a case on a component. It is advisable to keep the tests specialized in a particular situation. It is a mistake to write cases that test many functionalities. So in this phase, the programmer should retrieve or create only one instance of the component or functional unit that they want to test.
  2. Execution of the component. Given the component retrieved from the previous step, the next step is to invoke its execution, whether it is a function or a method of a class. This invocation must be done with known parameters, so that it is known in advance what the result should be if the operation is correct.
  3. Result verification. By calling the functional unit with known arguments and assuming that it is a deterministic functionality (i.e., that for the same parameters, it will always provide the same result), the result obtained by the execution of that logic is checked. If the provided result is equal to the expected one, the test passes successfully. If not, an exception is thrown indicating the error. This usually triggers the termination of the application build process.

It is important to emphasize that tests should verify only one functionality. They should be small and concise, so in any project hundreds of tests can accumulate normally. Small and specific tests are easier to maintain, test, and survive application changes more frequently.

How to Program with TDD using Spring Boot

If you already have a project built with Spring as the result of following the steps outlined in how to create an application with Spring Boot, incorporating TDD is very simple because Spring provides the dependencies and guidelines on how to perform testing for such programs.

If the project is built with Maven, using Gradle would be similar. You just need to include the base dependency responsible for grouping all the libraries to perform and execute the tests. The dependency to include in the pom.xml file is as follows:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Including the version in the dependency is not necessary if the project has the Spring project as its parent, as indicated in the tutorial. However, including it adds the jUnit library, among others, to the project, which is necessary for the first test.

Next, the programmer can create a simple test in the specified location as shown below:

// **src/test/java/org/eadp/test/MyTest.java**

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
public class MyTest {

    @Test
    public void myTest() {
        // Initialization phase
        MyComponent mc = new MyComponent();

        // Execution phase
        int res = mc.doSomeLogic(1L);

        // Verification phase
        // it is expected that the result (res) equals 1 (Long)
        Assert.assertEquals(1L,res);
    }
}

Spring provides a runner that provides the instantiation of the entire Spring context and therefore the management of dependencies within tests. This allows the programmer to initialize required components using new, or to use dependency injection via @Autowired as an attribute of the MyTest class. If you want to learn more about using Spring and how contexts work, you can visit the article Introduction to Spring Boot.

The programmer should create a large number of classes and methods similar to these to try to cover most of the implemented functionalities. Even tests that test different paths of the same logic should be included. For example, when there's an if-else statement, two test cases should be added, one for each branch of the conditional, to ensure that all lines of code are executed at least once.

Tests can usually be executed directly from the programming editor being used. Most of the time, simply positioning the cursor over the test and right-clicking will bring up a contextual menu with options like "run test" or "debug test". If not, the execution can always be forced using the corresponding Maven command:

mvn test

The Maven output after running the tests indicates the number of tests executed and how many had a satisfactory response:

[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]

From here, it is the task of the team of programmers to create each and every test case collected from the requirements catalog. The tests should be programmed in a high-level Java language, creating the necessary component or service classes, along with those intended to transport the required information at each step. Always ensure good component decomposition according to their responsibility.

Good separation into components or small, specialized classes will facilitate their verification in tests and the reuse of written logic across different modules of the application.

Conclusions

Applying TDD from the beginning of any project is very beneficial both in terms of guarantees for the work done and in defining the scope of the project. To define them, it is necessary for the user or client to transfer the knowledge they have and what they expect to cover with the information system. This is an important task as it will be necessary to resolve any ambiguities that arise, especially before starting to implement any function.

If you are a TDD user, we would be delighted if you share your experiences with us, whether they are positive or negative, to further expand the understanding of test-driven programming. Leave us your opinion!

Stay Connected

Newsletter

Stay up to date with the latest in technology and business! Subscribe to our newsletter and receive exclusive updates directly to your inbox.

Online Meeting

Don't miss the opportunity to explore new possibilities. Schedule an online meeting with us today and let's start building the future of your business together!

  • :D
  • :)
  • ;]
  • :0
  • :}
  • ;)
  • :>

Join the Team

We have a large portfolio of trainees who combine their academic training with experience at Arteco, learning firsthand from those on the front lines. We carry out an intensive training program aimed at rapid incorporation into real development teams.

Person running through the desert representing Arteco Consulting's Team Building
  • :)
  • :0
  • :D
  • ;)
  • :]