Code coverage
Program execution |
---|
General concepts |
Types of code |
Compilation strategies |
|
Notable runtimes |
|
Notable compilers & toolchains |
|
In
Code coverage was among the first methods invented for systematic software testing. The first published reference was by Miller and Maloney in Communications of the ACM, in 1963.[3]
Coverage criteria
To measure what percentage of code has been executed by a test suite, one or more coverage criteria are used. These are usually defined as rules or requirements, which a test suite must satisfy.[4]
Basic coverage criteria
There are a number of coverage criteria, but the main ones are:[5]
- Function coverage – has each function (or subroutine) in the program been called?
- Statement coverage – has each statement in the program been executed?
- Edge coverage – has every edge in the control-flow graph been executed?
- Branch coverage – has each branch (also called the if and case statements) been executed? For example, given an if statement, have both the true and false branches been executed? (This is a subset of edge coverage.)
- Branch coverage – has each branch (also called the
- Condition coverage – has each Boolean sub-expression evaluated both to true and false? (Also called predicate coverage.)
For example, consider the following C function:
int foo (int x, int y)
{
int z = 0;
if ((x > 0) && (y > 0))
{
z = x;
}
return z;
}
Assume this function is a part of some bigger program and this program was run with some test suite.
- Function coverage will be satisfied if, during this execution, the function
foo
was called at least once. - Statement coverage for this function will be satisfied if it was called for example as
foo(1,1)
, because in this case, every line in the function would be executed—includingz = x;
. - Branch coverage will be satisfied by tests calling
foo(1,1)
andfoo(0,1)
because, in the first case, bothif
conditions are met andz = x;
is executed, while in the second case, the first condition,(x>0)
, is not satisfied, which prevents the execution ofz = x;
. - Condition coverage will be satisfied with tests that call
foo(1,0)
,foo(0,1)
, andfoo(1,1)
. These are necessary because in the first case,(x>0)
is evaluated totrue
, while in the second, it is evaluated tofalse
. At the same time, the first case makes(y>0)
false
, the second case does not evaluate(y>0)
(because of the lazy-evaluation of the boolean operator), the third case makes ittrue
.
In programming languages that do not perform short-circuit evaluation, condition coverage does not necessarily imply branch coverage. For example, consider the following Pascal code fragment:
if a and b then
Condition coverage can be satisfied by two tests:
a=true
,b=false
a=false
,b=true
However, this set of tests does not satisfy branch coverage since neither case will meet the if
condition.
Fault injection may be necessary to ensure that all conditions and branches of exception-handling code have adequate coverage during testing.
Modified condition/decision coverage
A combination of function coverage and branch coverage is sometimes also called decision coverage. This criterion requires that every
Condition/decision coverage requires that both decision and condition coverage be satisfied. However, for
For example, consider the following code:
if (a or b) and c then
The condition/decision criteria will be satisfied by the following set of tests:
a | b | c |
---|---|---|
true | true | true |
false | false | false |
However, the above tests set will not satisfy modified condition/decision coverage, since in the first test, the value of 'b' and in the second test the value of 'c' would not influence the output. So, the following test set is needed to satisfy MC/DC:
a | b | c |
---|---|---|
false | true | false |
false | true | true |
false | false | true |
true | false | true |
Multiple condition coverage
This criterion requires that all combinations of conditions inside each decision are tested. For example, the code fragment from the previous section will require eight tests:
a | b | c |
---|---|---|
false | false | false |
false | false | true |
false | true | false |
false | true | true |
true | false | false |
true | false | true |
true | true | false |
true | true | true |
Parameter value coverage
Parameter value coverage (PVC) requires that in a method taking parameters, all the common values for such parameters be considered. The idea is that all common possible values for a parameter are tested.
Other coverage criteria
There are further coverage criteria, which are used less often:
- Linear Code Sequence and Jump (LCSAJ) coverage a.k.a. JJ-Path coverage – has every LCSAJ/JJ-path been executed?[9]
- Path coverage – Has every possible route through a given part of the code been executed?
- Entry/exit coverage – Has every possible call and return of the function been executed?
- Loop coverage – Has every possible loop been executed zero times, once, and more than once?
- State coverage – Has each state in a finite-state machine been reached and explored?
- Data-flow coverage – Has each variable definition and its usage been reached and explored?[10]
Some of the coverage criteria above are connected. For instance, path coverage implies decision, statement and entry/exit coverage. Decision coverage implies statement coverage, because every statement is part of a branch.
Full path coverage, of the type described above, is usually impractical or impossible. Any module with a succession of decisions in it can have up to paths within it; loop constructs can result in an infinite number of paths. Many paths may also be infeasible, in that there is no input to the program under test that can cause that particular path to be executed. However, a general-purpose algorithm for identifying infeasible paths has been proven to be impossible (such an algorithm could be used to solve the halting problem).[14] Basis path testing is for instance a method of achieving complete branch coverage without achieving complete path coverage.[15]
Methods for practical path coverage testing instead attempt to identify classes of code paths that differ only in the number of loop executions, and to achieve "basis path" coverage the tester must cover all the path classes.[citation needed][clarification needed]
In practice
This section needs additional citations for verification. (February 2015) |
The target software is built with special options or libraries and run under a controlled environment, to map every executed function to the function points in the source code. This allows testing parts of the target software that are rarely or never accessed under normal conditions, and helps reassure that the most important conditions (function points) have been tested. The resulting output is then analyzed to see what areas of code have not been exercised and the tests are updated to include these areas as necessary. Combined with other test coverage methods, the aim is to develop a rigorous, yet manageable, set of regression tests.
In implementing test coverage policies within a software development environment, one must consider the following:
- What are coverage requirements for the end product certification and if so what level of test coverage is required? The typical level of rigor progression is as follows: Statement, Branch/Decision, Linear Code Sequence and Jump)
- Will coverage be measured against tests that verify requirements levied on the system under test (DO-178B)?
- Is the object code generated directly traceable to source code statements? Certain certifications, (i.e. DO-178B Level A) require coverage at the assembly level if this is not the case: "Then, additional verification should be performed on the object code to establish the correctness of such generated code sequences" (DO-178B) para-6.4.4.2.[16]
Software authors can look at test coverage results to devise additional tests and input or configuration sets to increase the coverage over vital functions. Two common forms of test coverage are statement (or line) coverage and branch (or edge) coverage. Line coverage reports on the execution footprint of testing in terms of which lines of code were executed to complete the test. Edge coverage reports which branches or code decision points were executed to complete the test. They both report a coverage metric, measured as a percentage. The meaning of this depends on what form(s) of coverage have been used, as 67% branch coverage is more comprehensive than 67% statement coverage.
Generally, test coverage tools incur computation and logging in addition to the actual program thereby slowing down the application, so typically this analysis is not done in production. As one might expect, there are classes of software that cannot be feasibly subjected to these coverage tests, though a degree of coverage mapping can be approximated through analysis rather than direct testing.
There are also some sorts of defects which are affected by such tools. In particular, some race conditions or similar real time sensitive operations can be masked when run under test environments; though conversely, some of these defects may become easier to find as a result of the additional overhead of the testing code.
Most professional software developers use C1 and C2 coverage. C1 stands for statement coverage and C2 for branch or condition coverage. With a combination of C1 and C2, it is possible to cover most statements in a code base. Statement coverage would also cover function coverage with entry and exit, loop, path, state flow, control flow and data flow coverage. With these methods, it is possible to achieve nearly 100% code coverage in most software projects. [17]
Usage in industry
Test coverage is one consideration in the safety certification of avionics equipment. The guidelines by which avionics gear is certified by the Federal Aviation Administration (FAA) is documented in DO-178B[16] and DO-178C.[18]
Test coverage is also a requirement in part 6 of the automotive safety standard ISO 26262 Road Vehicles - Functional Safety.[19]
See also
- Cyclomatic complexity
- Intelligent verification
- Linear code sequence and jump
- Modified condition/decision coverage
- Mutation testing
- Regression testing
- Software metric
- Static program analysis
- White-box testing
- Java code coverage tools
References
- ISBN 978-1621140184. Retrieved 16 June 2016.
- ^ Williams, Laurie; Smith, Ben; Heckman, Sarah. "Test Coverage with EclEmma". Open Seminar Software Engineering. North Carolina State University. Archived from the original on 14 March 2016. Retrieved 16 June 2016.
- ISSN 0001-0782.
- ^ Paul Ammann, Jeff Offutt (2013). Introduction to Software Testing. Cambridge University Press.
- ISBN 0-471-46912-2.
- ^ Position Paper CAST-10 (June 2002). What is a "Decision" in Application of Modified Condition/Decision Coverage (MC/DC) and Decision Coverage (DC)?
- ^ MathWorks. Types of Model Coverage.
- ^ "Unit Testing with Parameter Value Coverage (PVC)".
- ^ M. R. Woodward, M. A. Hennell, "On the relationship between two control-flow coverage criteria: all JJ-paths and MCDC", Information and Software Technology 48 (2006) pp. 433-440
- ^ Ting Su, Ke Wu, Weikai Miao, Geguang Pu, Jifeng He, Yuting Chen, and Zhendong Su. "A Survey on Data-Flow Testing". ACM Comput. Surv. 50, 1, Article 5 (March 2017), 35 pages.
- ^ ECSS-E-ST-40C: Space engineering - Software. ECSS Secretariat, ESA-ESTEC. March, 2009
- ^ C. Prause, J. Werner, K. Hornig, S. Bosecker, M. Kuhrmann (2017): Is 100% Test Coverage a Reasonable Requirement? Lessons Learned from a Space Software Project. In: PROFES 2017. Springer. Last accessed: 2017-11-17
- ^ Martin Fowler's blog: TestCoverage. Last accessed: 2017-11-17
- ISBN 978-0-8493-7340-4; via Google Book Search
- ISBN 978-1-4200-4057-9.
- ^ a b RTCA/DO-178B, Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics, December 1, 1992
- ISBN 978-81-7722-260-9.
- ^ RTCA/DO-178C, Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics, January, 2012.
- ^ ISO 26262-6:2011(en) Road vehicles -- Functional safety -- Part 6: Product development at the software level. International Standardization Organization.