3 reasons to monitor cyclomatic complexity - Embedded.com

3 reasons to monitor cyclomatic complexity

Advertisement

Cyclomatic Complexity measurements are a simple metric that developers and teams can use to not just minimize their function complexity, but also ensure that they are testing all the paths through their code.

(Source: flickr/CC BY-SA 2.0)

I often feel like McCabe’s Cyclomatic Complexity is a fundamental metric that every software manager and developer in the world must surely track. Yet again and again I am stunned to discover how few know about and use Cyclomatic Complexity. Cyclomatic Complexity is a measurement that can be performed on software functions to measure the number of linearly independent paths in that function. Stated another way, it tells us how many branches there are in each function. Why might a developer want to track Cyclomatic Complexity? In today’s post, we will explore the three primary reasons to monitor cyclomatic complexity.

Reason #1 – It tells us the risk that a function contains undiscovered bugs.

In software development, we are constantly managing risk. The risk that we will deliver on time or not. The risk that we will run out of money before the product ships. The risk that a function we’ve written and tested as bugs that we have yet to uncover! Cyclomatic Complexity tells us the subjective risk that a given function has for containing a bug. For example, the table below provides the widely accepted Cyclomatic Complexity ranges and the risk associated with them.

Developers want to make sure that their functions stay very close to the 1 – 10 range to minimize the risk of undiscovered bugs. In fact, any function with more than fifty linearly independent paths is untestable, which obviously contains a very high risk for bugs.

Reason #2 – It tells us the risk that modifying a function will inject a bug

Have you ever tried to make changes to a function that sprawled across several hundred lines of code? It’s often stressful, tiring, and time consuming. Why? Because it usually doesn’t work out so well. A minor change, and things break. Fix it, and something else breaks. Large, complex functions often contain too many paths for our human, short term memories, to keep track of at one time! The result is bugs in the code.

Cyclomatic Complexity provides us with a numeric value that tells use the risk that a function contains a bug, but also the risk that a new bug will be injected into the code if we try to modify the function. Tracking Cyclomatic Complexity can help us to determine if we are getting ready to step into a quagmire, or whether the changes we are going to make will go smoothly. Take a moment to examine the Risk of Bug Injection table below [1][2]. For a simple function with complexity less than 11, the risk is only 5%! However, a function complexity of between 11 and 20, and suddenly there is a 20% risk! The risk only gets worse with rising complexity.

Reason #3 – It tells us the minimum number of test cases required to test our functions

The first two reasons to track Cyclomatic Complexity really drive us towards properly managing software risks and minimizing complexity within our software. My favorite reason to track Cyclomatic Complexity though is because it tells us the minimum number of tests cases required to test our functions successfully. For example, if you just wrote a function that has a Cyclomatic Complexity of twelve, you need at least twelve test cases to test each path through the function. In fact, the chances are you’ll need more than twelve to test boundary conditions with variable values and so forth. If you only have three test cases for that function, then the probability that there are bugs in the function are relatively high.

Even though I like to use Test-Driven Development when I write my embedded software, I still will use the Cyclomatic Complexity values to help me track that I haven’t overlooked anything. Cyclomatic Complexity in these cases can help act as a sanity check to make sure that developers test all the paths through their code. Don’t forget though, just because you test every path or get 100% test coverage doesn’t mean that there still aren’t bugs in the code. The tests just might not have been designed to catch them.

Conclusions

Cyclomatic Complexity measurements are a simple metric that developers and teams can use to not just minimize their function complexity, but also ensure that they are testing all the paths through their code. You’ll find that Cyclomatic Complexity measurements can be found in simple free tools like pmccabe or Metrix++, and in commercial metric tracking tools as well. I would recommend that developers use them during development and as part of the reporting process in your CI/CD pipelines. You’ll find that the ultimate reason for monitoring Cyclomatic Complexity is that it will save your companies time, money, and provide a higher quality code base.

References

[1] McCabe, Thomas Jr. Software Quality Metrics to Identify Risk. Presentation to the Department of Homeland Security Software Assurance Working Group, 2008.

[2] (http://www.mccabe.com/ppt/SoftwareQualityMetricsToIdentifyRisk.ppt#36) and Laird, Linda and Brennan, M. Carol. Software Measurement and Estimation: A Practical Approach. Los Alamitos, CA: IEEE Computer Society, 2006.


Jacob Beningo is an embedded software consultant who specializes in real-time, microcontroller-based systems. He actively promotes software best practices through numerous articles, blogs, and webinars on topics from software architecture design, embedded DevOps, and implementation techniques. Jacob has 20 years of experience in the field and holds three degrees including a Masters of Engineering from the University of Michigan.

Related Contents:

For more Embedded, subscribe to Embedded’s weekly email newsletter.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.