Unit Testing

Bread Crumbs: Home - SW_Dev_Proc - Impl - Unit Tst


Unit tests are structural, white box tests that should attempt to provide maximum execution path coverage including off-nominal (error) paths.

Unit testing is typically highly coupled to code development activities with high frequency iterations and is therefore difficult to distill from the coding activities. For this reason, this software development process includes unit testing as part of the implementation phase.

Unit tests may involve using interactive debuggers in order to force the flow of execution down certain paths that are hard to reach using extern stimuli. Unit testing also requires the creation of test harnesses, test stubs, and code instrumentation.

There are a variety of sophisticated tools that can be used to test for code coverage, adherence to coding guidelines, and memory leaks. As mentioned earlier, interactive debuggers can be of great assistance both for debugging and testing esoteric paths. IDEs or Integrated Development Environments often include some of these tools in a consistent, seamlessly integrated user interface.

There are two basic classes of code analysis tools, static analyzers and dynamic analyzers. For the sake of convenience, static analyzers can be run as part of a build by making the tool invocations targets of the makefile. Often times, dynamic analyzers require the placement of code hooks in order for them to perform the analysis at run-time. These code hooks can also be injected into the code at build time via tool invocations made in the makefile.

In the end, simple source code instrumentation which requires no external tools can be the most effective way to unit test source code thereby gaining confidence in the correctness of its implementation. The problem with overly intrusive forms of testing, like using interactive debuggers in timing-sensitive scenarios, is that sometimes the mere act of testing changes the very nature of what is being tested. Debuggers, memory profilers, and other types of run-time-active tools can have a huge impact on the speed at which code gets executed. If the test scenario is timing sensitive, then these types of tools would only get in the way. It is important to use the correct method for a given testing situation.

The following unit-testing-related topics are described on this page:

Flowgraph Analysis


An example of the type of analysis that goes into creating unit test plans follows.

Flow Graph - White Box Testing PNG

Cyclomatic Complexity

The cyclomatic complexity of a program's flow graph provides the number of independent paths in a program.

The cyclomatic complexity of any connected graph, G, is calculated by using the following formula:

CC(G) = Number_of_Edges - Number_of_Nodes + 2

CC (G) = 18 - 11 + 2 = 9

Nine regions were identified in the flow graph for the Cooking Control Function.  These regions are labeled R1 through R9 and are shown in the table below.

Region

Path

Test 

R1

1, 2, 3, 6, 10, 2, 11

Test 1

R2

1, 2, 3, 4, 10, 2, 11

Test 2

R3

1, 2, 3, 5, 4, 10, 2, 11

Test 3

R4

1, 2, 3, 4, 5, 11

Test 4

R5

1, 2, 3, 6, 7, 7, 8, 10, 2, 11

Test 5

R6

1, 2, 3, 6, 7, 7, 8, 9, 8, 10, 2, 11

Test 6

R7

1, 2, 3, 6, 7, 7, 8, 9, 11

Test 7

R8

1, 2, 3, 6, 7, 8, 10, 2, 11

Test 8

R9

1, 2, 11

Test 9



V-Model Diagram

The unit test suite needs to correlate very closely to the functional flow and data defined in the detail design. Unit tests should exercise as many paths as possible to ensure that algorithms are correctly implement, error handling works correctly, and there are no serious flaws such as infinite loops or infinite recursion.
V-Model Diagram - Unit Testing PNG Refer to the detailed design often during unit-testing to make sure no required features are overlooked. Unit test plans should focus on gaining confidence in algorithm implementation and error-handling. Path coverage is an important consideration as well.

No part of this work should be produced or used without the permission of the authors: Michael Turner and Dr. Sharon A White.