Black Box vs White Box Testing Techniques - II

Black Box vs White Box Testing Techniques - II

Last time, the black box testing techniques were introduced: Equivalence Partitioning, Boundary Value Analysis, Decision Table Testing, and State Transition Testing. Today, I am going to cover the white box testing techniques. Since the white box testing derives the test case from production code, the code coverage can be calculated through tests. Some examples of white box testing techniques are

  • Control flow testing

  • Branch coverage

  • Statement coverage

Based on the production code, control flow graph can be generated. The control flow graph shows all possible path with given branches and statements. Whenever code line includes "if" condition, two choices are available. This is called branch. Every valid code line is called statement in a given function.

Here is an example of code to determine if given measured voltage is whether undervoltage or not.

#define UNDERVOLTAGE_LOWER_THRESHOLD 40    //4.0V
#define UNDERVOLTAGE_UPPER_THRESHOLD 48    //4.8V

bool is_undervoltage(uint8_t measured_voltagex10)
{
    bool result = false;
    if (measured_voltagex10 >= UNDERVOLTAGE_LOWER_THRESHOLD )
    {
        if (measured_voltagex10 < UNDERVOLTAGE_UPPER_THRESHOLD )
        {
            result = true;
        }
        else
        {//do nothing1
        }
    }
    else
    {//do nothing2
    }
}

Here is the control flow graph based on code above:

First branch is align with first if condition. Left branch is continue with second if condition. Right branch is align with "do nothing2". The most left second branch is align with "result = true".

Depending on the given value, different control flow would be taken.

When measured_voltagex10 is 39,

When measured_voltagex10 is 40,

When measured_voltagex10 is 49,

Combining all three test cases will give 100% code coverage. Picking only three right values is enough to cover all branch and statement coverage. While I draw the control flow graph, it is helpful to understand structural of the given code.

Q: How to calculate branch coverage?

A: number of executed branches / total number of branches. In this example, there are total number of 4 branches shown below.

  • When measured_voltagex10 is 39, one branch is covered. Therefore, the branch coverage is 1/4.

  • When measured_voltagex10 is 40, two branches are covered. Therefore, the branch coverage is 2/4.

  • When measured_voltagex10 is 49, two branches are covered. Therefore, the branch coverage is 2/4.

Q: How to calculate statement coverage?

A: number of executed statements / total number of statements. In this example, there are total number of statements of 17 shown below.

  • When measured_voltagex10 is 39, 10 statements are covered. Therefore, the statement coverage is 10/17.

  • When measured_voltagex10 is 40, 11 statements are covered. Therefore, the statement coverage is 11/17.

  • When measured_voltagex10 is 49, 11 statements are covered. Therefore, the statement coverage is 11/17.

    Typically, code coverage, branch coverage, statement coverage are calculated by accumulating all existing test cases. In branch coverage example, the first test case is covered branch#2. The second test case is covered branch#1, 3. The third test case is covered branch#1, 4. When three test cases were written, the branch coverage is calculated as 100% because {2} U {1, 3} U {1, 4} = {1, 2, 3, 4}. The code coverage and statement coverage are 100% as well with three test cases. This strategy can detect dead code and unhandled cases. Not always code coverage 100% is necessary in real life, however, it can give developer some ideas to review if this is intentionally written that specific way.

Did you find this article valuable?

Support Hyunwoo Choi by becoming a sponsor. Any amount is appreciated!