Here is another helpful tool provided by Visual Studio 2010 to its users...
Code metrics is a set of software measures that provide developers better insight into the code they are developing. By taking advantage of code metrics of Visual Studio 2010, developers can understand which types and/or methods should be reworked or more thoroughly tested. Development teams can identify potential risks, understand the current state of a project, and track progress during software development.
The following list shows the code metrics results that Visual Studio calculates:
- Maintainability Index – Calculates an index value between 0 and 100 that represents the relative ease of maintaining the code. A high value means better maintainability.
- Cyclomatic Complexity – Measures the structural complexity of the code. It is created by calculating the number of different code paths in the flow of the program. A program that has complex control flow will require more tests to achieve good code coverage and will be less maintainable.
- Depth of Inheritance – Indicates the number of class definitions that extend to the root of the class hierarchy. The deeper the hierarchy the more difficult it might be to understand where particular methods and fields are defined or/and redefined.
- Class Coupling – Measures the coupling to unique classes through parameters, local variables, return types, method calls, generic or template instantiations, base classes, interface implementations, fields defined on external types, and attribute decoration. Good software design dictates that types and methods should have high cohesion and low coupling. High coupling indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types.
- Lines of Code – Indicates the approximate number of lines in the code. The count is based on the IL code and is therefore not the exact number of lines in the source code file. A very high count might indicate that a type or method is trying to do too much work and should be split up. It might also indicate that the type or method might be hard to maintain.
Today we will discuss about Complexity metrics. Most Important part of project or development metrics, So that before hitting Code Metrics of Visual Studio 2010. We can understand why its so important part of development life cycle.
Complexity metrics
The following metrics measure the complexity of executable code within methods. This includes both the internal complexity of a single method and the complexity of the data flow in and out of a method.
High complexity may result in bad understandability and more errors. Complex methods also need more time to develop and test. Therefore, excessive complexity should be avoided. Too complex methods should be simplified by rewriting or splitting into several methods.
Complexity is often positively correlated to code size. A big program or function is likely to be complex as well. These are not equal, however. A method with relatively few lines of code might be far more complex than a long one. We recommend the combined use of LOC and complexity metrics to detect complex code.
CC Cyclomatic complexity
Cyclomatic complexity is probably the most widely used complexity metric in software engineering. Defined by Thomas McCabe, it's easy to understand, easy to calculate and it gives useful results. It's a measure of the structural complexity of a procedure.
How to calculate cyclomatic complexity?
CC = Number of decisions + 1
Thus, cyclomatic complexity equals the number of decisions plus one. What are decisions? Decisions are caused by conditional statements. they are If..Then..Else, Select Case, For..Next, Do..Loop, While..Wend/End While, Catch and When.
The cyclomatic complexity of a procedure with no decisions equals 1.
There is no maximum value since a method can have any number of decisions.
Cyclomatic complexity, also known as V(G) or the graph theoretic number, is calculated by simply counting the number of decision statements. A multiway decision, the Select Case statement, is counted as several decisions. This version of the metric does not count Boolean operators such as And and Or, even if they add internal complexity to the decision statements.
Construct | Effect on CC | Reasoning |
If..Then | +1 | An If statement is a single decision. |
ElseIf..Then | +1 | ElseIf adds a new decision. |
Else | 0 | Else does not cause a new decision. The decision is at the If. |
Select Case | +1 for each Case | Each Case branch adds one decision in CC. |
Case Else | 0 | Case Else does not cause a new decision. The decisions were made at the other Cases. |
For [Each] .. Next | +1 | There is a decision at the start of the loop. |
Do..Loop | +1 | There is a decision at Do While|Until or alternatively at Loop While|Until. |
Unconditional Do..Loop | 0 | There is no decision in an unconditional Do..Loop without While or Until. * |
While..Wend
While..End While | +1 | There is a decision at the While statement. |
Catch | +1 | Each Catch branch adds a new conditional path of execution. Even though a Catch can be either conditional (catches specific exceptions) or unconditional (catches all exceptions), we treat all of them the same way. * |
Catch..When | +2 | The When condition adds a second decision. * |
.
Variations to cyclomatic complexity
Cyclomatic complexity comes in a few variations as to what exactly counts as a decision.
CC2 Cyclomatic complexity with Booleans ("extended cyclomatic complexity")
CC2 = CC + Boolean operators
CC2 extends cyclomatic complexity by including Boolean operators in the decision count. Whenever a Boolean operator (And, Or, Xor, Eqv, AndAlso, OrElse) is found within a conditional statement, CC2 increases by one. The conditionals considered are: If, ElseIf, Select, Case, Do, Loop, While, When. The reasoning behind CC2 is that a Boolean operator increases the internal complexity of the branch. You could as well split the conditional statement in several sub-conditions while maintaining the complexity level.
Alternative names: CC2 is sometimes called
ECC extended cyclomatic complexity or
strict cyclomatic complexity.
CC3 Cyclomatic complexity without Cases ("modified cyclomatic complexity")
CC3 = CC where each Select block counts as one
CC3 equals the regular CC metric, but each Select Case block is counted as one branch, not as multiple branches. In this variation, a Select Case is treated as if it were a single big decision. This leads to considerably lower complexity values for procedures with large Select Case statements. In many cases, Select Case blocks are simple enough to consider as one decision, which justifies the use of CC3.
Alternative name: CC3 is sometimes called
modified cyclomatic complexity.
Summary of cyclomatic complexity metrics
Metric | Name | Boolean operators | Select Case | Alternative name |
CC | Cyclomatic complexity | Not counted | +1 for each Case branch | Regular cyclomatic complexity |
CC2 | Cyclomatic complexity with Booleans | +1 for each Boolean | +1 for each Case branch | Extended or strict cyclomatic complexity |
CC3 | Cyclomatic complexity without Cases | Not counted | +1 for an entire Select Case | Modified cyclomatic complexity |
CC, CC2 or CC3 — which one to use? This is your decision. Pick up the one that suits your use best. CC is the original version and is probably the most widely used. CC3 provides the lowest values, CC comes next. CC2 is the highest variant, the most pessimistic one, one might say. All of them are heavily correlated, so you can achieve good results with any of them.
Values of cyclomatic complexity
A high cyclomatic complexity denotes a complex method that's hard to understand, test and maintain. There's a relationship between cyclomatic complexity and the "risk" in a method .
CC | Type of procedure | Risk |
1-4 | A simple procedure | Low |
5-10 | A well structured and stable procedure | Low |
11-20 | A more complex procedure | Moderate |
21-50 | A complex procedure, alarming | High |
>50 | An error-prone, extremely troublesome, untestable procedure | Very high |
The original, usual limit for a maximum acceptable value for cyclomatic complexity is 10. Other values, such as 15 or 20, have also been suggested. Regardless of the exact limit, if cyclomatic complexity exceeds 20, you should consider it alarming. Methods with a high cyclomatic complexity should be simplified or split into several smaller methods.
Cyclomatic complexity equals the minimum number of test cases you must execute to cover every possible execution path through your methods. This is important information for testing. Carefully test methods with the highest cyclomatic complexity values.
Bad fix probability
There is a frequently quoted table of "bad fix probability" values by cyclomatic complexity. This is the probability of an error accidentally inserted into a program while trying to fix a previous error.
CC | Bad fix probability |
1-10 | 5% |
20-30 | 20% |
>50 | 40% |
approaching 100 | 60% |
As the complexity reaches high values, changes in the program are likely to produce new errors.
Cyclomatic complexity and Select Case
The use of multi-branch statements (Select Case) often leads to high cyclomatic complexity values. This is a potential source of confusion. Should a long multiway selection be split into several procedures?
Although a procedure consisting of a single multiway decision may require many tests, each test should be easy to construct and execute. Each decision branch can be understood and maintained in isolation, so the method is likely to be reliable and maintainable. Therefore, it is reasonable to exempt methods consisting of a single multiway decision statement from a complexity limit. Note that if the branches of the decision statement contain complexity themselves, the rationale and thus the exemption does not automatically apply. However, if all the branches have very low complexity code in them, it may well apply.
Resolution: For each method, either limit cyclomatic complexity to 10 (or another sensible limit) or provide a written explanation of why the limit was exceeded.
DECDENS Decision Density
Cyclomatic complexity is usually higher in longer methods. How much decision is there actually, compared to lines of code? This is where you need decision density (also called cyclomatic density).
DECDENS = CC / LLOC
This metric shows the average cyclomatic density of the code lines within the procedures of your project. Single-line procedure declarations aren't counted since cyclomatic complexity isn't defined for them. The denominator is the logical lines of code metric.
TCC Total Cyclomatic Complexity
The total cyclomatic complexity for a project or a class is calculated as follows.
TCC = Sum(CC) - Count(CC) + 1
In other words, CC is summed over all methods. Count(CC) equals the number of methods. It's deducted because the complexity of each method is 1 or more. This way, TCC equals the number of decision statements + 1 regardless of the number of methods these decisions are distributed in.
Depth of nesting metrics
The following few metrics measure nesting levels. It is assumed that the deeper the nesting, the more complex the code.
DCOND Depth of Conditional Nesting
Depth of conditional nesting, or nested conditionals, is related to cyclomatic complexity. Whereas cyclomatic complexity deals with the absolute number of branches, nested conditionals counts how deeply nested these branches are.
The recommended maximum for DCOND is 5. More nesting levels make the code difficult to understand and can lead to errors in program logic. If you have too many levels, consider splitting the method. You may also find a way to rewrite the logic with a Select Case statement, or an easier-to-read If..Then..ElseIf..Else structure.
Although it might seem to give a lower DCOND, it's not recommended to join multiple conditions into a single, big condition involving lots of And, Or and Not logic.
DLOOP Depth of Looping
Depth of looping equals the maximum level of loop nesting in a procedure. Target at a maximum of 2 loops in a procedure.
Happy reading...
In next coming posts we will discuss each point of code metrics and will see how to use it with some examples...