Code quality – Cyclomatic complexity

It is good to improve the quality of your code. Especially when you write a lot and when you work with a team. It is also an advantage for personal projects. This allows for more reliable systems and above all it allows to adopt good reflexes.
There are many advantages: improved maintainability, testability …
Cyclomatic complexity corresponds to the number of different possible sequences in a method or a function. The result increases with the number of decision points (if, case, while …).
When the cyclomatic complexity is high, the function becomes difficult to test. The risk of adding errors to the program is greater.
It’s a simple tool, very useful and it’s a good indicator to improve the quality of coding.

The code quality is related to the Cyclomatic complexity.

Cyclomatic complexityReliability riskBug injection risk during a modification
1 - 10Simple function
Low risk
5%
11 - 20Intermediate function
Moderate risk
20%
21 - 50Complex function
High risk
40%
> 51Intestable function
Very high risk.
60%

Ideally, to get 100% test coverage, the number of unit tests should be equal to the cyclomatic complexity of the function being tested.
However, it is good practice to maintain the lowest possible cyclomatic complexity when possible. Even for programs with nonexistent test objectives.

I use a free tool that gives me complete satisfaction: Lizard

Lizard installation

Lizard is written in Python and works with many different operating systems. But you must have Python installed on your machine. It analyzes many languages such as C / C ++, Java, C #, JavaScript, Objective-C, Swift, Python, Ruby, PHP …

Python installation

  • Windows : Download and install Python.
    Add the path of the Python executables to the PATH environment variable.
  • Linux : Install Python using the package manager of your distribution.
    On Debian:
sudo apt-get install python3
  • MacOS : Install Python using brew.
brew install python

Pip update

python -m pip install -U pip

Lizard installation

python -m pip install lizard

Usage

Without parameters, Lizard analyzes all the source files with a known language. You can only select a language with the “-l” option.

The tool returns the following parameters after analysis:
– nloc: Number of line of code
– CCN: cyclomatic complexity
– Function occurrence counter
– Function parameter counter

Analysis of source files in the current directory :

python -m lizard

The acceptable limit of the number of cyclomatic complexity is configurable with the “-C” option (by default the limit is fixed at 15)

python -m lizard -C 50

Exclude a directory from the analysis :

python -m lizard -x"./exclude/*"

Integration in MPLAB

To execute code analysis with Lizard in MPLAB. Add the Lizard run command in the properties of the MPLAB project as shown :

MPLAB project configuration for Lizard tool

In this example, the files present in the “mcc_generated_files” directory are not analyzed.

Finally, during compilation, the MPLAB console displays the results of the Lizard analysis. If a limit is exceeded, compilation fails

MPLAB analysis result of the Lizard tool

Integration into PlatformIO

PlatformIO is installed in Visual Studio Code and allows you to use a modern IDE to program microcontrollers (Arduino, STM32, ESP …).
PlatformIO uses its own Python virtual environment. It is therefore necessary to install the lizard module in the virtual Python environment.

Lizard installation

Using a terminal, go to the directory “C:\Users\<username>\.platformio\penv\Scripts” (Windows) or the directory “/Users/<username>/.platformio/penv” ( Linux and MacOS).

Proceed to pip update and lizard installation:

python -m pip install -U pip
python -m pip install lizard

Integration of lizard in a project

To execute a command before compilation, you must create a custom python script (see PlatformIO documentation).

Creation of the python script

Create a python file in your project. ex: “extra_script.py”.

# Import global construction environment and isolated construction environment
Import("env")
# import module
import os

print("Code analysing ...")
os.system("python -m lizard")

Add the following line to the project configuration file :

extra_script = pre:extra_script.py

Example of file “platformio.ini”:

Example of platformio.ini file

Then, during compilation, the VSCode terminal displays the results of the Lizard analysis.

PlatformIO analysis result of the Lizard tool

Conclusion

The analysis of code quality with a calculation of the Cyclomatic Complexity is a good start. The “Lizard” tool written in Python is easily integrated into many development environments. But it’s just an indicator. Other tools and good practices are also necessary to improve the quality of coding (code convention, unit test, documentation …)