Unit Testing

Testing can be performed at different levels.

Testing Pyramid illustrates the relationship between the number of tests and the effort required to create them.

Unit Tests are the simplest and most numerous. They are usually written by developers while implementing a feature (details).

The Goal of Unit Testing is to verify the correctness of modules (functions, classes) in isolation and to catch defects early in development.

The Testing Pyramid
Testing Pyramid

Function for testing

Let’s act as a developer and write a function that adds two integers sum.

We’ll use pseudocode during development — informal code that is easier to read and understand.

sum(a, b) {

    declare a variable c

    perform addition a + b
    store the sum in a variable c

    return the variable c
}

Pseudocode

public int sum(int a, int b) {

    int c;


    c = a + b;


    return c;
}

Java code

Example Unit Test

A unit test defines the expected and actual results of a function execution.

If the expected and actual results match, the test passes PASS, otherwise, the test fails FAIL.

int expected = 3; //expected result

int actual = sum(1, 2); //actual result

expected == actual;

PASS

== equals sign

int expected = 2147483648;

int actual = sum(2147483646, 2);

expected != actual;

FAIL

!= not equals sign

Food for thought: Integer overflow

Code Coverage

The completeness of testing is measured using code coverage. However, 100% coverage does not guarantee the absence of bugs. It only shows which parts of the code are actually executed during a test run.

In the figure, line 9 is highlighted in red because it was not covered by a test. In other words, the function sum was never called with arguments a and b whose sum would satisfy the condition on line 8.

unit-tests
Code coverage view in IntelliJ IDEA
Task

Examine the function sum and select argument values that will provide full code coverage .

The variables a, b and c are of type int, which can store values from -2147483648 to 2147483647. Exceeding these limits produces unexpected results.

Test the function sum with different arguments:

a =
b =
C = 0
public int sum(int a, int b) {

    if (a + b > 2147483646) {
        out.println("Be careful with big numbers!");
    }

    int c = a + b;

    return c;
}
Which arguments will provide full code coverage?
a =
b =
Sidebar arrow