In previous posts, I’ve highlighted the importance of testing as a guide for improving software products. It’s so important that it allows development to be oriented toward meeting requirements and, therefore, business objectives. Yes, and of course, you know it’s important. It sounds logical that you need evidence that what you’re coding actually works, but then, how do you do it? That’s what we’ll cover next.

1. Introduction

Welcome to this series of articles dedicated to software testing, which aims to comprehensively explore the concepts necessary to define and execute it. Let’s get started!

There are various types of testing that guide software development. Depending on the needs, it is possible to have stricter control over the code flow, maintaining consistency and providing visibility into the content down to the value of each of the defined variables. This type of testing is known as white box testing because it allows us to see the entire operation of the code. However, generally, having complete control over the flow consumes a lot of time and effort, and it is not necessary to have complete visibility, only in sections where we are interested in debugging.

Other solutions stand out for having enough control to know only that the code actually produces the expected outputs. This type of testing is known as black box testing because the content of the data that the code may have on a specific line is unknown; however, the final result is known.

2. Unit tests

Unit testing stands out among black-box testing. These tests focus on the outputs of sections of code, typically accompanied by software code itself. That’s right! You write code to test code.

Unit testing encompasses several concepts that are useful when working with code, regardless of its language. Below, we’ll outline the most important ones:

  • Asserts: Asserts are the core of unit tests; they are the reason for their existence, because they specify how you compare code objects, usually comparing primitive data types. Finally, asserts are the reserved words within unit test code where you expect the output of your code to present the results you specify.
  • Initializers: Initializers are to unit tests what constructors are to classes; they are functions that declare or initialize specific objects of data types.
  • Finalizers: These are a type of “destructor,” without destroying the created test object. Just like constructors, they are executed after their execution has finished.
  • Mocks: These are vital when creating objects of highly coupled classes, and are used to mock the creation of object instances on which the class depends by creating empty objects used within the coupled class. This is especially useful when testing instances of classes such as the main class, which instantiates all the classes in an application chain, ignoring the problematic creation of class instances and allowing the developer to focus on testing the content of the class itself.

This type of testing is so popular that the most popular programming languages ​​already have libraries that support this type of testing, and even IDEs already support it graphically.

Language Unit testing libraries IDE's
Javascript Jest, Jasmine, Mocha Webstorm
Java Junit Eclipse, Netbeans
Python Pytest PyCharm, PyDev, Spider
PHP PHPUnit PHPStorm
C++ Google Test Qt Creator, CLion

3. Unit test coverage

Coverage involves detecting how much software code has been covered by unit tests, with the goal of identifying which lines of code have been tested and which remain to be tested.

In coverage, a section of code is considered covered in the following cases: (i) the tests effectively execute the code components that have been called; (ii) the unit tests actually pass the assertions and the tests are correctly executed, including the calling of dependencies; and (iii) a section of code is explicitly ignored by the programmer.

Likewise, there are IDEs that support graphical visualization of these two scenarios.

Language Coverage libraries IDE's
Javascript jscoverage Webstorm
Java JaCoCo Eclipse, Netbeans
PHP Xdebug PHPStorm
C++ lcov Qt Creator


Note: The tables above present the IDEs that support unit testing and coverage libraries graphically, but all of them can execute these two features either by commands or by generating reports in html, xml, json and others.

4. Example

We will consider the following example of a Java class where it is necessary to verify one of its functions:

public class Sum {
    private int a;
    private int b;

    public Sum (int a, int b){
        this.a = a;
        this.b = b;
    }

    public int sum(){
        return a+b;
    }
} 

The corresponding unit test class, using the junit test library, assuming that you have already loaded said library in your environment and that you have the suma class in the root of your project, would be the following:

import Sum;

public class MyTest {
    
    @Test
    public void testSum () {
        Sum sum = new Sum(1,2);
        assertEquals(3, sum.sum());
    }
}

Assuming the Sum class is the only class you have in your environment, when you run junit coverage, your tests should cover 100% of the application, since the entire class is traversed for testing. Likewise, the tests are free of code errors (both compilation and execution).

5. Conclusions

Unit testing is a powerful software testing tool and a common tool for system developers, as it offers a faster and more reliable approach than most existing testing methodologies. Of course, there are processes, approaches, and methodologies, as well as international standards and test-oriented lifecycle models, all of which focus on the most appropriate way to test software, aiming to avoid dependence on “superhero” programmers who arrive to save the day from potential problems that organizations may not know how to resolve.

In subsequent posts, we will delve deeper into this topic. If you liked the content and find it acceptable to stay up-to-date with our publications, subscribe to the social media platforms we manage in the footer or register to receive emails about new posts. Also, if you think we missed something or would like us to delve deeper into a specific topic, please let us know in the comments.