unit testing

Autonomy of a unit test

What is a unit testing?

Unit test is a testing method, which covers one unit of code (e.g. a method in Java) per test case. The idea behind unit tests is to cover the source code on the lowest and narrow possible level. Unit tests should be a part of any developer’s workflow and dependent on work methodology either can be written before (test-driven development) or after the actual unit has been implemented.  

INTEGU - Unit test

Autonomy of a unit test

A unit test consist of three sections: Given, When, and Then (GWT-pattern). Although the structure is not always clear when reading other developer’s test code, it will always in some way follow this pattern.

Tip

In case you stumped upon a unit test, which is not clearly structure according to the GWT-pattern, I would encourage you to refactor the code into a format, which clearly indicates how it follows the GWT-pattern.

Given-section

In the “Given”-section of the unit test, it is the objective to create the necessary reconfiguration for the unit of code to be tested. If we are writing a test for the checkout method of a web shop, it will be necessary for the cart to contain one or more products.

When-section:

In the “When”-section of the unit test, it is the objective to initiate the method to be tested. Assuming the correct reconfiguration provided from the “Given”-section, the method should pass through the intended logical path. After the method has finished its flow, we will have to assert the output in the “Then”-section.  

Then-section:

In the “Then”-section the objective is to assert that the method returned and changed the state of the code to the expected values. The assertion can be done in many ways, but primarily I would use return values, fields comparisons and argument captures. Armed with these three methods of assertion, you should be able to achieve the necessary coverage for any unit of code.

Code Coverage VS Logical Branches

Dependent on the complexity of the unit of code it might be necessary to create more than one unit test to provide code coverage for the entire unit. Additionally, if we want to cover every logical branch of the unit, it will in most cases require even more unit tests. Let us take an example to illustrate this point.

The following method looks pretty simple and likely looks like something we would be able to find in the source code of any project. Notice how the if-statement is divided into two logical operations separated by an OR-operator. Developers should be familiar with the behaviour of the OR-operator and should therefore know that it will return true regardless of which of the individual statements are true.

public void updateCustomerState(String name, boolean isLoggedIn, boolean isNewCustomer) {
    if (isLoggedIn || isNewCustomer) {
        this.name = name;
    }
}

To provide 100% code coverage of this method, we simply need to make one of the statements return true. This will ensure that the unit test dives into the method and asserts the expected output. However, as mentioned in the previous section, code coverage is not always enough to provide a high quality assurance. Sometimes we need to assert the output of the method for each possible logical branch of the method. To achieve this, we will have to write a test for each of these logical branches. In this case, that translate to four unit tests:

  1. Statement A – FALSE – Statement B – FALSE = IF-Statement – FALSE
  2. Statement A – TRUE – Statement B – FALSE = IF-Statement – TRUE
  3. Statement A – FALSE – Statement B – TRUE = IF-Statement – TRUE
  4. Statement A – TRUE – Statement B – TRUE = IF-Statement – TRUE

Statement A = isLoggedIn (boolean)

Statement B = isNewCustomer (boolean)

To learn more about how to cover all logical branches of a method through unit testing, trying visiting the page on “Mutation Testing”, which provides an in-depth description of code complexity and developer tools for getting an overview of a method’s logical branches.  

Mutation Testing

What Is Mutation Testing – Beats 100% Code Coverage

About

Hi, I'm the Author

My name is Daniel H. Jacobsen and I’m a dedicated and highly motivated software developer with a masters engineering degree within the field of ICT. 

I have through many years of constantly learning and adapting to new challenges, gained a well-rounded understanding of what it takes to stay up to date with new technologies, tools and utilities. 

The purpose of this blog is to share both my learnings and knowledge with other likeminded developers as well as illustrating how these topics can be taught in a different and alternative manner.

If you like the idea of that, I would encourage you to sign up for the newsletter.

Cheers! 🍺

Didn't Find What You Were Looking For?

Generic selectors
Exact matches only
Search in title
Search in content
Scroll to Top
INTEGU - Cookie-consent

INTEGU uses cookies to personalize your experience and provide traceability for affiliate links. By using the website, you agree to these terms and conditions. To learn more see the privacy policy page.