Measuring maintainability; software metrics explained

Preview:

Citation preview

Measuring Maintainability Dennis de Greef

Dennis de Greef Software Developer at TransIP Meetup addict

Tech enthousiast Occasional speaker Bass player

Domotica Software architect Hardware hacker Infrastructure engineer

Talk roadmap - About static software analysis - Measuring lines of code - Measuring complexity - Measuring coupling

About software statistics

Measuring Lines of Code

How many lines of code? 1 <?php 2 3 /* this is a for-loop */ 4 for ($i = 0; $i < 100; $i++) 5 { 6 printf("hello"); 7 }

How many lines of code? 1 <?php 2 3 /** 4 * This is a for-loop 5 */ 6 for ($i = 0; $i < 100; $i++) printf("hello");

Depends on your definition

LOC: Physical lines of code LLOC: Logical lines of code CLOC: Comment lines of code NCLOC: Non-comment lines of code

Different types:

How many lines of code?

7 physical lines of code 3 logical lines of code 1 comment lines of code 6 non-comment lines of code

1 <?php 2 3 /* this is a for-loop */ 4 for ($i = 0; $i < 100; $i++) 5 { 6 printf("hello"); 7 }

How many lines of code?

6 physical lines of code 3 logical lines of code 3 comment lines of code 3 non-comment lines of code

1 <?php 2 3 /** 4 * This is a for-loop 5 */ 6 for ($i = 0; $i < 100; $i++) printf("hello");

Some statisticsLOC

PhysicalCLOC

CommentNCLOC

Non-CommentLLOCLogical

symfony-standard 371490 102161(27.50%)

269329(72.50%)

84262(22.68%)

zend-framework2 306097 112498(36.75%)

193599(63.25%)

56053(18.31%)

laravel-framework 78191 35156 (44.96%)

43035(55.04%)

11970 (15.31%)

cakephp 93455 42454 (45.43%)

51001 (54.57%)

17235 (18.44%)

phploc 2.1.2-17-gb6bfd40

PSR-2

PSR-2

PSR-2

PSR-2

WARNING!Don’t use these statistics as a form of measuring quality or productivity!

People will just ‘game’ the system

*applies different codestyle*

Use it to gain more insight about the application

“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”

--Bill Gates

composer require phploc/phploc$ phploc loc1.php phploc 2.0.2 by Sebastian Bergmann.!

Size Lines of Code (LOC) 7 Comment Lines of Code (CLOC) 1 (14.29%) Non-Comment Lines of Code (NCLOC) 6 (85.71%) Logical Lines of Code (LLOC) 3 (42.86%) Classes 0 (0.00%) Average Class Length 0 Average Method Length 0 Functions 0 (0.00%) Average Function Length 0 Not in classes or functions 3 (100.00%)

Measuring Complexity

• Cyclomatic Complexity • N-path Complexity

Complexity and quality are strongly related

Cyclomatic Complexity“It is a quantitative measure of the number of

linearly independent paths through a program's source code.”

M = E − N + 2PE = the number of edges of the graph. N = the number of nodes of the graph. P = the number of connected components.

http://www.literateprogramming.com/mccabe.pdf

Simply put:Counting of decision trees: - function - for(each) - while - if - case

Cyclomatic Complexity 1 <?php 2 3 function foo($a, $b) { 4 if($a) { 5 if($b) { 6 echo "Hello World"; 7 } 8 } 9 } 10

5 edges 4 nodes 1 compound

M = 5 − 4 + 2x1 = 3M = E − N + 2P

Cyclomatic Complexity8 edges 7 nodes 1 compound

M = 8 − 7 + 2x1 = 3M = E − N + 2P

1 <?php 2 3 function foo() { 4 if($a) { 5 echo '1'; 6 } else { 7 echo '2'; 8 } 9 if($b) { 10 echo '3'; 11 } else { 12 echo '4'; 13 } 14 }

Cyclomatic ComplexityHow many tests do we need?

M = 8 − 7 + 2x1 = 3

Complete branch coverage: foo(true, false) foo(false, true)

Code Coverage 1 <?php 2 3 function foo($a, $b) { 4 if($a) { 5 // ... 6 } 7 8 if($b) { 9 // ... 10 } 11 } 12 13 foo(true, false); 14 foo(false, true);

All paths are tested with these two function calls. This implies 100% code coverage. !

Or does it? What about: foo(false, false) foo(true, true) ?

Code CoveragePath coverage:

http://derickrethans.nl/path-branch-coverage.html

Xdebug 2.3.0

PHP_CodeCoverage: not supported

N-path Complexity

“The NPath complexity of a method is the number of acyclic execution paths through that method.”

“The NPath complexity of a method is the number of acyclic execution paths through that method.”

N-path Complexity

“The NPath complexity of a method is the number of acyclic execution paths through that method.”

N-path Complexity

N-path Complexity

Path coverage

M = E − N + 2PE = the number of edges of the graph. N = the number of nodes of the graph. P = the number of connected components.

N-path Complexity

foo(false, false) foo(true, false) foo(false, true) foo(true, true)

Cyclomatic Complexity = 3 N-path Complexity = 4

N-path is exponential

N-path Complexity

foo(false, false) foo(true, false) foo(false, true) foo(true, true)

Cyclomatic Complexity = 3 N-path Complexity = 4

N-path is exponential

Number of unique paths

N-path Complexity // … $count['staticMethods'], $count['methods'] > 0 ? ($count['staticMethods'] / $count['methods']) * 100 : 0, $count['publicMethods'], $count['methods'] > 0 ? ($count['publicMethods'] / $count['methods']) * 100 : 0, $count['nonPublicMethods'], $count['methods'] > 0 ? ($count['nonPublicMethods'] / $count['methods']) * 100 : 0, $count['functions'], $count['namedFunctions'], $count['functions'] > 0 ? ($count['namedFunctions'] / $count['functions']) * 100 : 0, // …

N-path Complexity

The method printResult() has an NPath complexity of 47683715820312500.

The configured NPath complexity threshold is 200.

Measuring Coupling

http://www.codemanship.co.uk/parlezuml/metrics/OO%20Design%20Principles%20&%20Metrics.pdf

Martin’s Metrics

Measuring CouplingCoupling between packages

Packages being either a namespace or composer package

Measuring Coupling

Afferent Coupling (Ca):"Amount of other packages depending on this class (incoming) !

Efferent Coupling (Ce):"Amount of dependencies of this class !

Instability (I):"Resilience to change, metric between 0 and 1. Where 0 is stable.

I = Ce / (Ce + Ca)

Measuring Coupling

Ca = 2

Ce = 3

I = Ce / (Ce + Ca)

I = 3 / (3+2)

I = 0,6

I = 0,0 = Completely stableI = 1,0 = Completely unstable

Measuring Coupling

Abstract:"Either an abstract class or interface !

Concrete:"Any class that is neither abstract or final !

Abstractness (A):"How abstract a package is, ratio between 0 and 1. Where 0 is concrete.

A = Abstract / (Abstract + Concrete)

Measuring CouplingPHPMD (PHP Mess Detector)

Can detect (code size rules): - Cyclomatic complexity - N-path complexity - Excessive method length - Too many methods - etcetera

1020010010

And other things- Clean Code - Design Rules - Naming Rules - Unused Code Rules

Integrating it all

http://jenkins-php.org/

Questions?

Thank youBig thanks to: !

Derick Rethans (Xdebug) Sebastian Bergmann"(PHPLOC, PHPunit, PHP_CodeCoverage) Thomas J. McCabe Sr: Cyclomatic Complexity Robert C. Martin: Lots of things!(nicknamed ‘Uncle Bob’) !

Many more…

Twitter: @dennisdegreef Blog: dennisdegreef.net IRC (Freenode): link0 Github: dennisdegreef / link0 PHPNL-Slack: link0 Joind.in: https://joind.in/14991

Recommended