NPath Complexity

NPath complexity is a complexity metric that measures complexity based on a graph approach. NPath complexity is the number of acyclic execution paths in a function, module, method, class or program. An acyclic execution path is a path through the function, module, method, class or program that does not include cycles, so no nodes are visited more than one time if we draw an execution path in the graph.

From a source perspective npath complexity can be interpreted as the number of possible execution combinations of some source code.

To explain how to calculate npath complexity we start with an example. It's a safe implementation of the JavaScript add operator that sets an operand to 0 if the operand is not a number.


module.exports = function add(num1, num2) {
  if (isNaN(num1)) {
    num1 = 0;
  }

  if (isNaN(num2)) {
    num2 = 0;
  }

  return num1 + num2;
};

This code example can be visualized as a control flow diagram

Flow Graph
Control Flow Diagram of Function add

In this function we can identify 4 execution paths:

Function add has a npath complexity of 4.

Dealing with high NPath Complexity

The best strategy to decrease the npath complexity of a function and as to increase the testability of a function is, to split up functions into smaller parts. In the source code example above we could extract a function getNumberOrZero to return the number passed as argument if the passed argument is a number or 0 if the passed number is not a number. So the above add function can be rewritten as


module.exports = function add(num1, num2) {
  return getNumberOrZero(num1) + getNumberOrZero(num2);
};

function getNumberOrZero(value) {
  if (isNaN(value)) {
    return 0;
  }

  return value;
}

This results in a npath complexity of 1 for function add and a npath complexity of 2 for function getNumberOrZero.