Content deleted Content added
Add banner {{Cleanup bare URLs}}. After at least 7 passes by @Citation bot since 20220903, this article still has 1 untagged bare URL ref |
Synapse554 (talk | contribs) m Moved to section on algebraic topology to its own heading, given its different context compared to the rest of the article |
||
(20 intermediate revisions by 14 users not shown) | |||
Line 1:
{{Short description|Measure of the structural complexity of a software program}}
'''Cyclomatic complexity''' is a [[software metric]] used to indicate the [[Programming complexity|complexity of a program]]. It is a quantitative measure of the number of linearly independent
▲'''Cyclomatic complexity''' is a [[software metric]] used to indicate the [[Programming complexity|complexity of a program]]. It is a quantitative measure of the number of linearly independent paths through a program's [[source code]]. It was developed by [[Thomas J. McCabe, Sr.]] in 1976.
Cyclomatic complexity is computed using the [[control-flow graph]] of the program
One [[software testing|testing]] strategy, called [[basis path testing]] by McCabe who first proposed it, is to test each linearly independent path through the program
url=http://users.csc.calpoly.edu/~jdalbey/206/Lectures/BasisPathTutorial/index.html|
title=Basis Path Testing|
Line 11 ⟶ 10:
==Description==
===Definition===
[[Image:control flow graph of function with loop and an if statement without loop back.svg|thumb|
where
[[Image:control flow graph of function with loop and an if statement.svg|thumb|
An alternative formulation of this, as originally proposed, is to use a graph in which each exit point is connected back to the entry point. In this case, the graph is [[strongly connected]]
This may be seen as calculating the number of [[linearly independent cycle]]s that exist in the graph
For a single program (or subroutine or method), {{mvar|P}}
<math display="block">M = E - N + 2.</math>
Cyclomatic complexity may
McCabe showed that the cyclomatic complexity of
url=https://www.froglogic.com/blog/tip-of-the-week/what-is-cyclomatic-complexity/| title=What exactly is cyclomatic complexity?|quote=To compute a graph representation of code, we can simply disassemble its assembly code and create a graph following the rules: ... |first=Sébastien|last=Fricker|date=April 2018|website=froglogic GmbH|access-date=October 27, 2018}}</ref> Decisions involving compound predicates like those found in [[high-level
▲title=What exactly is cyclomatic complexity?|quote=To compute a graph representation of code, we can simply disassemble its assembly code and create a graph following the rules: ... |first=Sébastien|last=Fricker|date=April 2018|website=froglogic GmbH|access-date=October 27, 2018}}</ref> Decisions involving compound predicates like those found in high-level languages like <code>IF cond1 AND cond2 THEN ...</code> should be counted in terms of predicate variables involved, i.e. in this example one should count two decision points, because at machine level it is equivalent to <code>IF cond1 THEN IF cond2 THEN ...</code>.<ref name="mccabe76"/><ref name="ecst">{{cite book|
title=Encyclopedia of Computer Science and Technology|
author1=J. Belzer |author2=A. Kent |author3=A. G. Holzman |author4=J. G. Williams|
Line 47 ⟶ 42:
pages=367–368}}</ref>
Cyclomatic complexity may be extended to a program with multiple exit points
where <math>\pi</math> is the number of decision points in the program
=== Interpretation ===▼
===Explanation in terms of algebraic topology===▼
In his presentation
An ''even subgraph'' of a graph (also known as an [[Eulerian path|Eulerian subgraph]]) is one where every [[Vertex (graph theory)|vertex]] is incident with an even number of edges; such subgraphs are unions of cycles and isolated vertices. In the following, even subgraphs will be identified with their edge sets, which is equivalent to only considering those even subgraphs which contain all vertices of the full graph.▼
* 1 - 10: Simple procedure, little risk▼
The set of all even subgraphs of a graph is closed under [[symmetric difference]], and may thus be viewed as a vector space over [[GF(2)]]; this vector space is called the ''cycle space'' of the graph. The [[cyclomatic number]] of the graph is defined as the dimension of this space. Since GF(2) has two elements and the cycle space is necessarily finite, the cyclomatic number is also equal to the 2-logarithm of the number of elements in the cycle space.▼
* 11 - 20: More complex, moderate risk▼
* 21 - 50: Complex, high risk▼
* > 50: Untestable code, very high risk▼
A basis for the cycle space is easily constructed by first fixing a [[Glossary of graph theory#Trees|spanning forest]] of the graph, and then considering the cycles formed by one edge not in the forest and the path in the forest connecting the endpoints of that edge; these cycles constitute a basis for the cycle space. Hence, the cyclomatic number also equals the number of edges not in a maximal spanning forest of a graph. Since the number of edges in a maximal spanning forest of a graph is equal to the number of vertices minus the number of components, the formula <math>E-N+P</math> above for the cyclomatic number follows.<ref>{{cite book▼
▲An
▲The set of all even subgraphs of a graph is closed under [[symmetric difference]], and may thus be viewed as a [[vector space]] over [[GF(2)]]
For the more topologically inclined, cyclomatic complexity can alternatively be defined as a relative [[Betti number]], the size of a [[relative homology]] group:▼
:<math>M := b_1(G,t) := \operatorname{rank}H_1(G,t),</math>▼
which is read as "the rank of the first homology group of the graph ''G'', relative to the terminal nodes ''t''". This is a technical way of saying "the number of linearly independent paths through the flow graph from an entry to an exit", where:▼
* "linearly independent" corresponds to homology, and means one does not double-count backtracking;▼
* "paths" corresponds to ''first'' homology: a path is a 1-dimensional object;▼
* "relative" means the path must begin and end at an entry or exit point.▼
▲A [[basis (linear algebra)|basis]] for the cycle space is easily constructed by first fixing a [[Glossary of graph theory#Trees|spanning forest]] of the graph, and then considering the cycles formed by one edge not in the forest and the path in the forest connecting the endpoints of that edge
▲
▲which is read as "the rank of the first [[Homology (mathematics)|homology]] group of the graph ''G''
It can also be computed via [[homotopy]]. If one considers a (connected) control-flow graph as a 1-dimensional [[CW complex]] called <math>X</math>, then the [[fundamental group]] of <math>X</math> will be <math>\pi_1(X) \cong \Z^{*n}</math>. The value of <math>n+1</math> is the cyclomatic complexity. The fundamental group counts how many loops there are through the graph, up to homotopy, and hence aligns with what we would intuitively expect.▼
▲* "linearly independent" corresponds to homology, and
▲* "relative" means the path must begin and end at an entry (or exit) point.
This cyclomatic complexity can be calculated. It may also be computed via absolute [[Betti number]] by identifying the terminal nodes on a given component, or drawing paths connecting the exits to the entrance. The new, augmented graph <math>\tilde G</math> obtains
▲It can also be computed via [[homotopy]].
▲=== Interpretation ===
▲In his presentation 'Software Quality Metrics to Identify Risk'<ref>http://www.mccabe.com/ppt/SoftwareQualityMetricsToIdentifyRisk.ppt</ref> for the Department of Homeland Security, Tom McCabe introduces the following categorisation to interpret cyclomatic complexity:
▲* 1 - 10 Simple procedure, little risk
▲* 11 - 20 More complex, moderate risk
▲* 21 - 50 Complex, high risk
▲* > 50 Untestable code, very high risk
==Applications==
===Limiting complexity during development===
One of McCabe's original applications was to limit the complexity of routines during program development
url=http://www.mccabe.com/pdf/mccabe-nist235r.pdf| title=Structured Testing: A Testing Methodology Using the Cyclomatic Complexity Metric|author1=Arthur H. Watson |author2=Thomas J. McCabe | year=1996|publisher=NIST Special Publication 500-235}}</ref>
===Measuring the "structuredness" of a program===
{{Main|Essential complexity (numerical measure of "structuredness")}} <!-- please update the link when that article is split, as it should be -->
Section VI of McCabe's 1976 paper is concerned with determining what the control-flow graphs (CFGs) of non-[[structured programming|structured program]]s look like in terms of their subgraphs, which McCabe
===Implications for software testing===
Line 135 ⟶ 108:
[[File:Control flow graph of function with two if else statements.svg|thumb|250px|right|The control-flow graph of the source code above; the red circle is the entry point of the function, and the blue circle is the exit point. The exit has been connected to the entry to make the graph strongly connected.]]
In this example, two test cases are sufficient to achieve a complete branch coverage, while four are necessary for complete path coverage. The cyclomatic complexity of the program is 3 (as the strongly connected graph for the program contains
In general, in order to fully test a module, all execution paths through the module should be exercised. This implies a module with a high complexity number requires more testing effort than a module with a lower value since the higher complexity number indicates more pathways through the code. This also implies that a module with higher complexity is more difficult
Unfortunately, it is not always practical to test all possible paths through a program. Considering the example above, each time an additional if-then-else statement is added, the number of possible paths grows by a factor of 2. As the program grows in this fashion, it quickly reaches the point where testing all of the paths becomes impractical.
One common testing strategy, espoused for example by the NIST Structured Testing methodology, is to use the cyclomatic complexity of a module to determine the number of [[white-box testing|white-box tests]] that are required to obtain sufficient coverage of the module. In almost all cases, according to such a methodology, a module should have at least as many tests as its cyclomatic complexity
As an example of a function that requires more than
* <code>c1()</code> returns true and <code>c2()</code> returns true
Line 156 ⟶ 129:
===Correlation to number of defects===
|journal=IEEE Transactions on Software Engineering|author1=Norman E Fenton |author2=Martin Neil |
url=http://www.eecs.qmul.ac.uk/~norman/papers/defects_prediction_preprint105579.pdf|
title=A Critique of Software Defect Prediction Models|
year=1999|volume=25|issue=3|pages=675–689|doi=10.1109/32.815326|citeseerx=10.1.1.548.2998 }}</ref> Some studies<ref name="schroeder99">{{cite journal| title=A Practical guide to object-oriented metrics|author=Schroeder, Mark|s2cid=14945518|year=1999|volume=1|issue=6|pages=30–36|journal=IT Professional |doi=10.1109/6294.806902}}</ref> find a positive correlation between cyclomatic complexity and defects
{{cite web |url=http://www.leshatton.org/TAIC2008-29-08-2008.html |title=The role of empiricism in improving the reliability of future software |author=Les Hatton |year=2008 |at=version 1.1}}</ref> that complexity has the same predictive ability as lines of code.
Studies that controlled for program size (i.e., comparing modules that have different complexities but similar size) are generally less conclusive, with many finding no significant correlation, while others do find correlation. Some researchers
{{cite book |title=Metrics and Models in Software Quality Engineering |author=Kan |pages=316–317 |publisher=Addison-Wesley |year=2003 |isbn=978-0-201-72915-3}}</ref> Although this relation
journal=Journal of Software Quality|
author=G.S. Cherf|
Line 169 ⟶ 142:
year=1992|volume=1|issue=3|pages=147–158|
issn=1573-1367|doi=10.1007/bf01720922|
s2cid=37274091}}</ref> Since program size is not a controllable feature of commercial software, the usefulness of
==See also==
Line 201 ⟶ 168:
* [http://www.mathworks.com/discovery/cyclomatic-complexity.html Generating cyclomatic complexity metrics with Polyspace]
* [http://www.leshatton.org/Documents/TAIC2008-29-08-2008.pdf The role of empiricism in improving the reliability of future software]
* [https://web.archive.org/web/20230203195937/https://www.cqse.eu/en/news/blog/mccabe-cyclomatic-complexity// McCabe's Cyclomatic Complexity and Why We Don't Use It]▼
▲* [https://www.cqse.eu/en/blog/mccabe-cyclomatic-complexity/ McCabe's Cyclomatic Complexity and Why We Don't Use It]
[[Category:Software metrics]]
|