73
Sebastian Marek, Software Architect Magic behind the numbers Software metrics in practice

PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Embed Size (px)

DESCRIPTION

We use static code analysis tools more often these days that create great reports and funky graphs. But do we understand what it all means? Software metrics tends to be magic numbers for a lot of people, but they don’t really have to be. Seb will introduce you to a few basic, the most popular software metrics and tools. He will explain to you what they mean and how you can use them to produce better software.

Citation preview

Page 1: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Sebastian Marek, Software Architect

Magic behind the numbers

Software metrics in

practice

Page 2: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

@proofek

•  a Pole living in Sheffield •  over 10 years PHP

experience •  co-author of 2 PHP books •  big fan of process

automation •  TDD and CI •  occasionally contributes

to open source projects •  wants to be a knight

Page 3: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Agenda

What I will be talking about •  Code metrics •  Design metrics

What I will not be talking about •  Project metrics

https://joind.in/4758

Page 4: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Most effective code quality measure

Page 5: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
Page 6: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

“It is the mapping of a particular characteristic of a measured entity to

a numerical value”

Source: Object-Oriented Metrics in Practice

What is a metric?

Page 7: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

“Good design quality metrics are not necessarily indicative of good designs. Likewise, bad design quality metrics are not necessarily indicative of bad

designs”

Source: Jdepend Docs

Software design

Page 8: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

System maintenance

•  Obsolete documentation •  Convoluted design •  Intensive patch mechanism (hacking) •  Large size •  Severe duplication •  Obsolete parts (dead code) •  Long build times •  Loss of original developers

Page 9: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Simple metrics

•  CLOC – comment lines of code •  ELOC – executable lines of code •  LOC – lines of code •  NCLOC – non comment lines of code •  NOP – number of packages •  NOC – number of classes •  NOM – number of methods

Page 10: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic Complexity (CYCLO)

Cyclomatic complexity measures the amount of decision logic in a single software

module.

Page 11: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic Complexity Number (CCN)

Conditional statements: •  ? •  case •  elseif •  for •  foreach •  if •  while

Page 12: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

CCN2

Conditional statements: •  ? •  case •  elseif •  for •  foreach •  if •  while

•  && •  || •  or •  and •  xor

Page 13: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity

Conditional statements: •  ? •  case •  elseif •  for •  foreach •  if •  while

•  && •  || •  or •  and •  xor •  catch

Page 14: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 15: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 16: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 17: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 18: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 19: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 20: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() { 1 if ($a == $b) { 2 if ($a1 == $b1) { 3 fiddle(); } elseif ($a2 == $b2) { 4 fiddle(); } else { fiddle(); } } elseif ($e == $f) { 5 for ($n = 0; $n < $h; $n++) { 6 fiddle(); } } else { fiddle(); } } }

Page 21: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - example

class Foo { public function example() {

6

if ($a == $b) { if ($a1 == $b1) { fiddle(); } elseif ($a2 == $b2) { fiddle(); } else { fiddle(); } } elseif ($e == $f) { for ($n = 0; $n < $h; $n++) { fiddle(); } } else { fiddle(); } } }

Page 22: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

phploc phploc 1.6.1 by Sebastian Bergmann.Directories: 6Files: 20Lines of Code (LOC): 5478 Cyclomatic Complexity / Lines of Code: 0.13Comment Lines of Code (CLOC): 2143Non-Comment Lines of Code (NCLOC): 3335Namespaces: 0Interfaces: 1Classes: 18 Abstract: 2 (11.11%) Concrete: 16 (88.89%) Average Class Length (NCLOC): 191Methods: 151 Scope: Non-Static: 143 (94.70%) Static: 8 (5.30%) Visibility: Public: 116 (76.82%) Non-Public: 35 (23.18%) Average Method Length (NCLOC): 22 Cyclomatic Complexity / Number of Methods: 3.72Anonymous Functions: 0Functions: 2Constants: 4 Global constants: 3 Class constants: 1

Page 23: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Cyclomatic complexity - thresholds

Low Avg High V.High Complexity 1-4 5-7 8-10 > 11

Page 24: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

JAVA

Metric Low Avg High V.High CYCLO/Line of code 0.16 0.20 0.24 0.36 LOC/Method 7 10 13 19.5 NOM/Class 4 7 10 15

Source: Object-Oriented Metrics in Practice (based on 45 Java projects)

Page 25: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

C++

Metric Low Avg High V.High CYCLO/Line of code 0.20 0.25 0.30 0.45 LOC/Method 5 10 16 24 NOM/Class 4 9 15 22.5

Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)

Page 26: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

WMC and AMW

Weighted Method Count – total complexity of a class

Average Method Weight – average complexity of a method

Page 27: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

JAVA

Metric Low Avg High V.High WMC 5 14 31 47 AMW 1.1 2.0 3.1 4.7 LOC/Class 28 70 130 195

Source: Object-Oriented Metrics in Practice (based on 45 Java projects)

Page 28: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

C++

Metric Low Avg High V.High WMC 4 23 72 108 AMW 1.0 2.5 4.8 7.0 LOC/Class 20 90 240 360

Source: Object-Oriented Metrics in Practice (based on 37 C++ projects)

Page 29: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Coverage report

Page 30: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
Page 31: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

C.R.A.P

Page 32: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

C.R.A.P

Change Risk Analysis and Predictions

Change Risk Analysis and Predictions

Page 33: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

C.R.A.P formula

Code coverage = 100%

Code coverage = 0%

Page 34: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
Page 35: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – acyclic execution path complexity

NPATH is an objective measure of software complexity related to the ease with which software can be comprehensively tested

Edgar H. Sibley

Page 36: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – acyclic execution path complexity

expressions Number of && and || operators in expression if NP(<if-range>)+NP(<expr>)+1 if-else NP(<if-range>)+NP(<else-range>)+NP(<expr>) while NP(<while-range>)+NP(<expr>)+1 for NP(<for-range>)+NP(<expr1>)+NP(<expr2>)+ NP(<expr3>)+1 break 1 continue 1 return 1 sequential 1 function call 1

Page 37: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 38: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) { fiddle(); 1 } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 39: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) { fiddle(); 1 } else { fiddle(); 2 } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 40: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) { 2 fiddle(); 1 } else { fiddle(); 2 } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 41: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) {

2 fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 42: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { if ($a1 == $b1) {

2 fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 43: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { 2 if ($a1 == $b1) {

2 fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 44: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) { 2 if ($a1 == $b1) {

2 fiddle(); } else { fiddle(); } } 3

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 45: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 46: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); 1 } } return true; } }

Page 47: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { 1 fiddle(); 1 } } return true; } }

Page 48: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { 1 fiddle(); 1 } 2 } return true; } }

Page 49: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) {

2 fiddle(); } } return true; } }

Page 50: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) {

2 fiddle(); } } return true; } }

Page 51: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { 3 for ($n = 0; $n < $h; $n++) {

2 fiddle(); } } return true; } }

Page 52: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { 3 for ($n = 0; $n < $h; $n++) {

2 fiddle(); } } 4 return true; } }

Page 53: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) {

4 for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 54: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

if ($a == $b) {

3

if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) {

4 for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; 1 } }

Page 55: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

NPATH – example class Foo { public function example() {

12

if ($a == $b) { if ($a1 == $b1) { fiddle(); } else { fiddle(); } }

if ($e == $f && $g == $z) { for ($n = 0; $n < $h; $n++) { fiddle(); } } return true; } }

Page 56: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

PHP Depend PHP_Depend 0.10.6 by Manuel PichlerParsing source files:.................... 20Executing CyclomaticComplexity-Analyzer:............. 261Executing ClassLevel-Analyzer:............ 247Executing CodeRank-Analyzer:. 28Executing Coupling-Analyzer:............. 267Executing Hierarchy-Analyzer:............ 246Executing Inheritance-Analyzer:. 30Executing NPathComplexity-Analyzer:.............. 283Executing NodeCount-Analyzer:........ 174Executing NodeLoc-Analyzer:.......... 205Generating pdepend log files, this may take a moment.Time: 00:05; Memory: 25.50Mb

Page 57: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

PHP Mess Detector

Page 58: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Overview pyramid

Page 59: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Size and complexity – direct metrics

Page 60: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Size and complexity – computed proportions

Page 61: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

System coupling – direct metrics

Page 62: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

System coupling – computed proportions

Page 63: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

System inheritance

Page 64: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Complete Overview Pyramid

Page 65: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

PHP

Metric Low Avg High CYCLO/LOC 0.16 0.20 0.24 LOC/NOM 7 10 13 NOM/NOC 4 7 10 NOC/NOP 6 17 26 CALLS/NOM 2.01 2.62 3.2 FANOUT/CALLS 0.56 0.62 0.68 ANDC 0.25 0.41 0.57 AHH 0.09 0.21 0.32

http://pdepend.org/

Page 66: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Metrics visualisation with Sonar

Page 67: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Metrics visualisation with Sonar

Page 68: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Violations reporting

Page 69: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

SIG Maintainability Model

-- - 0 + ++

Very bad Bad Average Good Very good

Page 70: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Technical Debt

Page 71: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Summary

“We believe that software metrics, in general, are just tools. No single metric can tell the whole story; it’s just one more data

point. “

“Metrics are meant to be used by developers, not the other way around – the metric should work for you, you should not have

to work for the metric. “

“Metrics should never be an end unto themselves. Metrics are meant to help you think, not to do the thinking for you.”

Alberto Savoia

Page 72: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Resources

•  PHP Depend - http://pdepend.org/ •  PHP Mess Detector - http://phpmd.org/ •  Manuel’s home page - http://manuel-pichler.de/ •  PHPUnit - http://www.phpunit.de/ •  phploc - http://sebastianbergmann.github.com/phploc/ •  Sonar - http://www.sonarsource.org/ •  “Object-Oriented Metrics in Practice” by Michele Lanza

and Radu Marinescu (ISBN 978-3540244295)

Page 73: PHP Benelux 2012: Magic behind the numbers. Software metrics in practice

Questions

Questions?

https://joind.in/4758