Squish CocoCode Coverage Measurement for C/C++
CoverageScanner first analyses the sequential statements to record each execution path. It determines which instructions need to be instrumented and places a flag to record their execution. To avoid performance problems, CoverageScanner groups all sequential instructions together and records their execution only once: before coverage instrumentation is usually called Statement Coverage. In the following version of the example, the instrumented statements are underlined:
In this example, lines 3 and 9 are not monitored since
lines 3, 9 and 10 are sequential operations. This doesn’t have
an impact concerning coverage because if line 10 is executed then
lines 3 and 9 must have be executed before it.
CoverageScanner’s
analysis of conditions determines which expressions are used in
conditional statements (if, while, for,
…).
These statements separate the execution path into two or more
branches.
Code coverage monitors execution by recording if
the condition was true or false during the application’s execution.
The analysis of Boolean expressions is used to determine which
combinations are used in
a conditional statements’ (if, while, for,
…) Boolean operations (and, or, …).
This makes it possible to have a more fine grained analysis of why
a particular code segment was executed.
In the example, the instrumented Boolean expressions are underlined:
Squish Coco’s analysis is not limited to control statements (such as
In the example, the instrumented Boolean expressions are underlined:
The statement 1.1.2 Code insertionAfter the detection phase, CoverageScanner inserts the instrumentation code itself as the following examples illustrate. (Note that the inserted code is displayed in bold blue.)
The generated instrumentation code that needs to be inserted to provide statement coverage for the earlier foo() function example means that the function’s code is transformed to the code shown here:
If we insert the instrumentation code necessary to support decision coverage into this example, the resulting code will look like this:
If we insert the instrumentation code necessary to support condition coverage into this example, the resulting code will look like this (except that we have wrapped one line to fit better on the page):
Here is what the code would look like if we inserted the partial instrumentation code for condition coverage (again, with one line wrapped):
1.1.3 Result of coverage analysisThe CoverageBrowser program features a graphical user interface which it uses to display the analysed results of the instrumentation. CoverageBrowser uses color coding to indicate statement status. For this manual we have used the same colors as the program, but in addition we have applied text effects to aid those reading a monochrome print out.
The output for the example would be:
The expression 1.2 PerformanceThe insertion of instrumentation increases the code size and also
affects the instrumented application’s performance—it will use more
memory and will run slower. Detailed measurements are available in the Appendix (see chap. benchmarks). 1.3 StatisticsSome developers write more lines of code than others simply by using a
particular coding style—for example, putting opening braces on a line
of their own rather than on the same line as, say, an if
statement. In view of this, Squish Coco computes its statistics using a
more subtle measure that isn’t susceptible the the vagaries of coding
style: its calculations are based on the number of executed instrumented
instructions compared with the total number of instrumented
instructions. Each simple instrumented instruction (return, break,
last instruction of a function, etc.) is recorded by one single
instrumentation. A fully instrumented condition in an
The statistics themselves depend of the type of instrumentation. It is
not generally possible to compare code coverage at branch level with
that at decision level: having 80% coverage at decision level, does
not tell us anything about the coverage at branch level, which could
be bigger or smaller. The only thing we can be sure of is that
reaching 100% coverage is more difficult with condition coverage than
with decision coverage and than branch coverage.
Chapter 2 Testing MethodologiesThis chapter discusses the various testing strategies that can be carried out so as to make the best use of the Squish Coco tools. 2.1 Coverage Hits vs. CountsIf we want to set very stringent standards for an application to ensure that it is of the highest possible quality, executing just portions of its code, or executing code just once, is insufficient. To address this issue the Squish Coco tools provide two possible approaches:
2.2 Testing StrategiesSquish Coco can be adapted to fit in with many different testing strategies, from unit tests during early development all the way through to complete product validation (e.g., acceptance tests). CoverageBrowser supports the merging of code coverage results at each stage of testing, and so provides a precise overview of the software’s overall quality. 2.2.1 Manual White Box TestsWhite box testing (a.k.a. clear box testing, glass box testing or structural testing) uses an internal perspective of the system to design test cases based on internal structure. It requires programming skills to identify all paths through the software. The tester chooses test case inputs to exercise paths through the code and determines the appropriate outputs. Interactive white box tests are easy to do using Squish Coco: once the application has been compiled with CoverageScanner, the test engineer can execute the application, and after each execution they can import the execution report into CoverageBrowserfor analysis. 2.2.2 Manual Black Box TestsBlack box testing takes an external perspective of the test object to derive test cases. These tests can be functional or non-functional, though usually functional. The test designer selects valid and invalid input and determines the correct output. There is no knowledge of the test object’s internal structure. Black box tests assume that test engineers have no knowledge of the application’s internals—they work purely in terms of inputs and the corresponding expected outputs (whether of data or of error reports for invalid input). For this kind of testing it is possible to follow the same pattern as
for white box testing, but without providing the test engineer with the
instrumentation database ( Squish Coco has a facility which makes black box testing possible
without disadvantaging test engineers. The CoverageBrowser tool can
generate an instrumentation database ( 2.2.3 Unit TestsUnit testing is a method by which individual units of source code are tested to determine if they are fit for use. A unit is the smallest testable part of an application. In procedural programming a unit could be an entire module but is more commonly an individual function or procedure. In object-oriented programming a unit is often an entire interface, such as a class, but could be an individual method. CoverageScanner supports the saving of the code coverage data generated by each unit test using its library. (see chap. unit-test) As long as all objects are well compiled2, it is possible to merge the unit tests instrumentation database into those of the real application. And so see the code coverage of the unit tests on the main application. 2.2.4 Automatic TestsSquish Coco allows us to annotate the execution report with the execution name and state. This does not require any specific library—the information can be inserted directly by editing the execution report before and after the execution of a test item. This makes it possible to integrate the report into an automatic testing framework or for use with a test executing script. (see chap. execution-name-status) |
|||||||||||||||||||||||||||||||||||||||