Cyclomatic Complexity
Cyclomatic Complexity: Definition, Formula, Calculation, Examples
Cyclomatic Complexity, also known as Code Complexity, is a software metric used to measure the complexity of a program. It was introduced by Thomas J. McCabe in 1976 and measures the number of linearly independent paths through a program’s source code.
Cyclomatic Complexity is widely used by software developers, testers, code reviewers, and quality engineers to understand how difficult a piece of code is to understand, test, maintain, and modify. Generally, a lower cyclomatic complexity indicates simpler code that is easier to maintain and test.
What is Cyclomatic Complexity?
Cyclomatic Complexity is a quantitative measure of the number of independent execution paths in a program. It is calculated from the program’s control flow, which represents how statements, conditions, loops, and branches are connected during execution.
Each independent path represents a unique flow through the program that should be considered when designing and executing tests.
For example, a method containing several if statements and loops has more possible execution paths than a simple sequential method. As the number of decision points increases, the Cyclomatic Complexity also increases.
Who Developed Cyclomatic Complexity?
Cyclomatic Complexity was developed by Thomas J. McCabe in 1976. The metric was introduced as a way to quantify the complexity of software and help engineering teams identify code that may be difficult to test and maintain.
Why is Cyclomatic Complexity Important?
Cyclomatic Complexity is important because highly complex code can be harder to understand, test, debug, and modify. Measuring complexity helps teams identify methods or modules that may require refactoring or additional testing.
1. Helps Identify Complex Code
A high Cyclomatic Complexity value indicates that a program contains many possible execution paths. Such code may deserve closer review and possible simplification.
2. Helps Estimate Testing Effort
Cyclomatic Complexity can be used to estimate the minimum number of independent paths that should be considered for basis path testing.
3. Improves Maintainability
Lower-complexity code is generally easier for developers to understand and modify. Reducing unnecessary branches can make future changes safer.
4. Supports Code Review
Development teams can use Cyclomatic Complexity as one of several indicators during code reviews to identify methods that may be difficult to maintain.
5. Helps Identify Refactoring Opportunities
When a method becomes excessively complex, the metric can indicate that the method may benefit from being split into smaller, focused methods.
Cyclomatic Complexity Formula
Cyclomatic Complexity can be calculated using a control flow graph with the following formula:
M = E – N + 2P
- M = Cyclomatic Complexity
- E = Number of edges in the control flow graph
- N = Number of nodes in the control flow graph
- P = Number of connected components, usually
1for a single program or method
For a single connected control flow graph, the formula is often simplified to:
M = E – N + 2
Cyclomatic Complexity Using Decision Points
For many practical programming examples, Cyclomatic Complexity can also be calculated by counting the number of decision points:
M = D + 1
Where:
- M = Cyclomatic Complexity
- D = Number of decision points
Depending on the programming language and the analysis tool, constructs such as if, while, for, case, and logical conditions such as && or || may contribute to complexity.
Simple Cyclomatic Complexity Example
Consider the following code:
if (age >= 18) {
if (hasLicense) {
System.out.println("Can drive");
} else {
System.out.println("License required");
}
} else {
System.out.println("Too young to drive");
}
This code contains two decision points:
if (age >= 18)if (hasLicense)
Using the decision-point formula:
M = D + 1
M = 2 + 1 = 3
Therefore, the Cyclomatic Complexity of this example is 3.
Understanding Independent Paths
An independent path is an execution path that introduces at least one new edge or decision outcome that was not included in previously considered paths.
For the example above, the three independent paths can be represented as:
- Age is less than 18.
- Age is 18 or older and the person has a driving license.
- Age is 18 or older and the person does not have a driving license.
These paths demonstrate why Cyclomatic Complexity is useful for test design: a complexity value of 3 indicates three independent paths in this example.
Cyclomatic Complexity and Control Flow Graph
A Control Flow Graph (CFG) is a graphical representation of the possible execution flow of a program.
In a control flow graph:
- Nodes represent statements or blocks of statements.
- Edges represent the flow of control between nodes.
- Decision nodes represent branches in program execution.
Cyclomatic Complexity can be calculated from this graph by using the formula M = E - N + 2P.
Cyclomatic Complexity and Software Testing
Cyclomatic Complexity has a strong relationship with white-box testing, particularly Basis Path Testing.
Basis Path Testing uses the control flow structure of a program to identify independent execution paths. The Cyclomatic Complexity value provides a theoretical minimum number of independent paths required for basis path coverage.
For example, if a method has a Cyclomatic Complexity of 5, at least five independent paths can be identified as a basis for structural testing.
Cyclomatic Complexity in Unit Testing
Developers can use Cyclomatic Complexity to identify methods that may require more unit test cases.
Consider two methods:
| Method | Cyclomatic Complexity | Testing Difficulty |
|---|---|---|
| Method A | 2 | Low |
| Method B | 8 | Higher |
| Method C | 15 | Very High |
Method C has significantly more independent paths than Method A. It may therefore require more careful unit testing and may be a good candidate for refactoring.
Common Constructs That Increase Cyclomatic Complexity
Several programming constructs can increase Cyclomatic Complexity, including:
ifstatementselse ifbrancheswhileloopsforloopsdo-whileloopsswitch/casebranches- Conditional operators such as
? : - Logical conditions involving
&&and||, depending on the metric implementation
Cyclomatic Complexity Levels
There is no universal complexity threshold that applies to every programming language or organization. However, engineering teams often use complexity ranges as practical indicators.
| Cyclomatic Complexity | General Interpretation |
|---|---|
| 1–5 | Usually simple and relatively easy to understand |
| 6–10 | Moderately complex; review may be useful |
| 11–20 | Complex; testing and maintenance may become more difficult |
| 20+ | Very complex; strong candidate for review and refactoring |
These ranges should be treated as guidelines rather than strict rules. The appropriate threshold depends on the application, programming language, architecture, risk level, and team’s coding standards.
Low vs High Cyclomatic Complexity
| Low Cyclomatic Complexity | High Cyclomatic Complexity |
|---|---|
| Fewer execution paths | Many execution paths |
| Easier to understand | Harder to understand |
| Usually easier to test | Requires more comprehensive testing |
| Generally easier to maintain | Maintenance can be difficult |
| Lower risk of introducing defects during changes | Changes can have more complicated effects |
| Often simpler design | May indicate opportunities for refactoring |
Advantages of Cyclomatic Complexity
- Provides a measurable indicator of code complexity.
- Helps identify code that may be difficult to test.
- Supports basis path testing.
- Helps prioritize code review and refactoring.
- Can be integrated into static code analysis and quality tools.
- Provides a useful metric for monitoring code quality trends.
Limitations of Cyclomatic Complexity
Cyclomatic Complexity is useful, but it should not be treated as the only measure of software quality.
A method with low Cyclomatic Complexity can still be difficult to understand because of poor naming, complicated data structures, excessive nesting, or unclear business logic. Similarly, some algorithms naturally require multiple branches and may have a higher complexity without necessarily being poorly designed.
Therefore, Cyclomatic Complexity should be evaluated together with other quality indicators such as code readability, duplication, test coverage, maintainability, coupling, and code review findings.
How to Reduce Cyclomatic Complexity
Developers can reduce excessive Cyclomatic Complexity through several refactoring techniques.
1. Break Large Methods into Smaller Methods
Large methods can often be split into smaller methods, each responsible for a single task.
2. Reduce Deep Nesting
Using guard clauses and early returns can sometimes reduce unnecessary nested conditional structures.
3. Simplify Conditional Logic
Complex conditional expressions can sometimes be simplified or moved into dedicated methods.
4. Use Polymorphism Where Appropriate
In object-oriented applications, replacing large conditional structures with polymorphism or strategy-based designs can reduce branching in individual methods.
5. Remove Duplicate Logic
Duplicated conditional logic can increase maintenance difficulty. Extracting common logic into reusable functions can improve code structure.
Cyclomatic Complexity vs Code Coverage
Cyclomatic Complexity and Code Coverage are related to software testing but measure different things.
| Cyclomatic Complexity | Code Coverage |
|---|---|
| Measures structural complexity | Measures how much code has been exercised by tests |
| Focuses on execution paths and decisions | Focuses on executed statements, branches, paths, or conditions |
| Can help estimate basis path testing effort | Can indicate which portions of code are covered by tests |
A project can have high code coverage and still contain highly complex code. Similarly, low complexity does not automatically mean that sufficient test coverage exists.
Cyclomatic Complexity vs Number of Lines of Code
Lines of Code (LOC) measures code size, while Cyclomatic Complexity measures the number of independent control-flow paths.
A 100-line method may have low complexity if it is mostly sequential, while a 20-line method can have high complexity if it contains many conditional branches.
Tools Used to Measure Cyclomatic Complexity
Many static analysis and code quality tools can calculate Cyclomatic Complexity for source code. Examples include tools and platforms used for languages such as Java, JavaScript, Python, C#, C, and C++.
Examples include:
- SonarQube
- SonarLint
- Checkstyle
- PMD
- ESLint and JavaScript complexity plugins
- Visual Studio code analysis tools
- Various IDEs and static analysis platforms
Best Practices for Using Cyclomatic Complexity
Use Cyclomatic Complexity as an indicator rather than an absolute measure of code quality. Establish reasonable thresholds for your project, review methods that exceed those thresholds, and combine the metric with test coverage, maintainability analysis, code reviews, and developer judgment.
It is also useful to track complexity over time. A method whose complexity continually increases may be a stronger refactoring candidate than one that has a stable, moderately high value because of a well-understood algorithm.
Frequently Asked Questions About Cyclomatic Complexity
What is Cyclomatic Complexity?
Cyclomatic Complexity is a software metric that measures the number of linearly independent paths through a program’s control flow.
Who introduced Cyclomatic Complexity?
Thomas J. McCabe introduced Cyclomatic Complexity in 1976.
What is the formula for Cyclomatic Complexity?
The graph-based formula is M = E – N + 2P. For a single connected component, it becomes M = E – N + 2. In many practical cases, it can also be calculated as number of decision points + 1.
Why is Cyclomatic Complexity important in testing?
It helps identify the number of independent control-flow paths and can be used to support Basis Path Testing and test effort estimation.
Is lower Cyclomatic Complexity always better?
Not necessarily. Lower complexity is generally easier to manage, but some algorithms and business rules naturally require multiple branches. The metric should be considered along with readability, maintainability, architecture, and risk.
What is a high Cyclomatic Complexity value?
There is no single universal threshold. In practice, higher values indicate more complex control flow and may justify additional testing, code review, or refactoring.
Conclusion
Cyclomatic Complexity is an important software engineering metric for understanding the structural complexity of source code. Developed by Thomas J. McCabe in 1976, it measures the number of linearly independent paths through a program and provides valuable insight into testing and maintainability challenges.
The metric can be calculated using M = E – N + 2P or, in many practical situations, by counting decision points and adding one. When used correctly, Cyclomatic Complexity helps developers and testers identify complex code, estimate structural testing effort, and find opportunities for refactoring.
However, Cyclomatic Complexity should not be used in isolation. Combining it with code coverage, static analysis, maintainability metrics, code reviews, and sound engineering judgment provides a more complete view of software quality.
In summary, understanding and managing Cyclomatic Complexity can help teams build code that is easier to test, understand, maintain, and evolve.