Development By The Numbers - ConFoo Edition

  • 825 views
Uploaded on

In this talk, we'll explore some of the tools available for measuring software quality. We'll dive into some of the theory behind the metrics that they analyze while looking at some real world …

In this talk, we'll explore some of the tools available for measuring software quality. We'll dive into some of the theory behind the metrics that they analyze while looking at some real world applications of those metrics. We'll also explore how to use these tools to gain valuable insight into legacy codebases.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
825
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
7
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Development By The Numbers
  • 2. We Are Going To Measure Complexity
  • 3. Why Should We Care About Complexity?
  • 4. - Geer et al. "The Central Enemy Of Reliability is Complexity"
  • 5. Complexity And Quality Are Strongly Related
  • 6. Basic Metrics
  • 7. Cyclomatic Complexity
  • 8. Cyclomatic Complexity Number Of "Decision Points" In A Routine
  • 9. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 10. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 11. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; } 4
  • 12. Simple Right?
  • 13. Cyclomatic Complexity (Single Method) 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  • 14. Cyclomatic Complexity (Average Per Method) 1 - 2: Low Complexity 2 - 4: Moderate Complexity 4 - 6: High Complexity 6+: Very High Complexity
  • 15. Compare: Average CC per Method Wordpress: 6.28 Drupal 7: 3.02 Drupal 8: 2.10 Symfony 2: 1.81 Zend Framework 2: 2.62 Laravel: 1.79
  • 16. Cyclomatic Complexity (Average Per Line Of Code) .01 - .05: Low Complexity .05 - .10: Moderate Complexity .10 - .15: High Complexity .15+: Very High Complexity
  • 17. Compare: Average CC per LOC Wordpress: 0.20 Drupal 7: 0.04 Drupal 8: 0.07 Symfony 2: 0.06 Zend Framework 2: 0.10 Laravel: 0.07
  • 18. N-Path Complexity
  • 19. N-Path Complexity Number Of "Unique Paths" In A Routine
  • 20. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 21. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 22. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 23. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 24. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  • 25. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; } 4
  • 26. They Are The Same?
  • 27. Not Generally!
  • 28. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: NPath:
  • 29. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: NPath:
  • 30. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 31. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 32. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 33. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 34. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 35. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 36. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 37. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 38. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath:
  • 39. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath: 8
  • 40. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; } CC: 4 NPath: 8 2^(CC-1)
  • 41. N-Path Complexity <16: Low Complexity 17-128: Moderate Complexity 129-1024: High Complexity 1025+: Very High Complexity
  • 42. N-Path Complexity Minimum Number Of Tests Required To Completely Test A Routine
  • 43. N-Path Complexity entity_load() CC: N-Path:
  • 44. N-Path Complexity entity_load() CC: 2 N-Path:
  • 45. Cyclomatic Complexity 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  • 46. N-Path Complexity entity_load() CC: 2 N-Path: 2
  • 47. N-Path Complexity drupal_http_request() CC: N-Path:
  • 48. N-Path Complexity drupal_http_request() CC: 41 N-Path:
  • 49. Cyclomatic Complexity 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  • 50. N-Path Complexity drupal_http_request() CC: 41 N-Path: 25,303,344,960
  • 51. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 2 Terabytes Worth Of Tests
  • 52. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 412 DVD's Worth Of Tests
  • 53. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 670k Drupals Worth Of Tests
  • 54. And That's Not The Worst One!
  • 55. N-Path Complexity _date_repeat_rrule_process() CC: N-Path:
  • 56. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path:
  • 57. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256
  • 58. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256 ,250,000,000,000
  • 59. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256 ,250,000,000,000 ,000,000,000
  • 60. To Completely Test _date_repeat_rrule_process() At 1 Line Of Code Per Test Would Require 336T 2009's Worth Of Tests
  • 61. MicroSD Card ● About 387GB / cm^3 ○ Current Density Record
  • 62. MicroSD Card ● About 387GB / cm^3 ○ Current Density Record ● About 184PB / Butt-Load ○ The text from every piece of written material in the world...
  • 63. MicroSD Card ● About 387GB / cm^3 ○ Current Density Record ● About 184PB / Butt-Load ○ The text from every piece of written material in the world... ● About 387PB / m^3 ○ About 20 “MegaUpload.com Sites”
  • 64. MicroSD Card ● About 387GB / cm^3 ○ Current Density Record ● About 184PB / Butt-Load ○ The text from every piece of written material in the world... ● About 387PB / m^3 ○ About 20 “MegaUpload.com Sites” ● About 387YB / km^3 ○ About 100,000 Google’s
  • 65. To Completely Test _date_repeat_rrule_process() At 1 Line Of Code Per Test Would Require 1 Greenland Ice Cap of microSD cards Worth Of Tests
  • 66. N-Path Complexity compose_pm() CC: N-Path:
  • 67. N-Path Complexity compose_pm() CC: 331 N-Path:
  • 68. Because Sending Private Messages Is Hard...
  • 69. N-Path Complexity compose_pm() CC: 331 N-Path:
  • 70. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665
  • 71. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028
  • 72. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269
  • 73. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269 ,333,860,397,338
  • 74. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269 ,333,860,397,338 ,867,187,500,000
  • 75. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269 ,333,860,397,338 ,867,187,500,000 ,000,000,000,000
  • 76. N-Path ComplexityCC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269 ,333,860,397,338 ,867,187,500,000 ,000,000,000,000 ,000,000,000,000
  • 77. To Completely Test compose_pm() At 1 Line Of Code Per Test Would Require 1B BlackHoles Worth Of Tests
  • 78. CRAP
  • 79. CRAP (Change Risk Analysis Predictions)
  • 80. CC = Cyclomatic Complexity (method) COV = Test Coverage (percent) CRAP = CC + (CC^2 * (1 - COV)^3)
  • 81. CRAP Relates Complexity And Test Coverage
  • 82. CRAP Increasing Test Coverage Lowers CRAP Decreasing Complexity Lowers CRAP
  • 83. CRAP A Low Complexity Method With No Tests Is Good
  • 84. CRAP A Low Complexity Method With Good Tests Is Great
  • 85. CRAP A Moderate Complexity Method With Good Tests Is OK
  • 86. CRAP A Moderate Complexity Method With No Tests Is CRAP
  • 87. CRAP < 5: GREAT Code 5 - 15: Acceptable Code 15-30: Eih... Code 30+: CRAPpy Code
  • 88. A Word On Refactoring
  • 89. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; }
  • 90. function foo2($a, $b, $c) { $d = 0; $d += checkValue($a); $d += checkValue($b); $d += checkValue($c); return $d; } function checkValue($v) { if ($v) { return $v; } return 0; }
  • 91. Quality Is A Tradeoff Between Complexity And Bloat
  • 92. How Do We Measure These Metrics?
  • 93. Quiz: Only 2 Major QA Tools NOT Made By Germans What Are They?
  • 94. PHP-CodeSniffer Behat
  • 95. Let’s Talk Tools
  • 96. PHPLOC
  • 97. PHPLOC By Sebastian Bergmann
  • 98. PHPLOC By Sebastian Bergmann Command Line Tool
  • 99. PHPLOC By Sebastian Bergmann Command Line Tool Summarizes An Entire Codebase
  • 100. $ phploc path/to/Drupal7/ Directories: 73 Files: 180 Lines of Code (LOC): 63347 Cyclomatic Complexity / Lines of Code: 0.04 Comment Lines of Code (CLOC): 19321 Non-Comment Lines of Code (NCLOC): 44026
  • 101. Namespaces: 0 Interfaces: 1 Traits: 0 Classes: 38 Abstract: 2 (5.26%) Concrete: 36 (94.74%) Average Class Length (NCLOC): 197
  • 102. Methods: 433 Scope: Non-Static: 378 (87.30%) Static: 55 (12.70%) Visibility: Public: 255 (58.89%) Non-Public: 178 (41.11%) Average Method Length (NCLOC): 17 Cyclomatic Complexity / Number of Methods: 3.02 Anonymous Functions: 0 Functions: 521 Constants: 22 Global constants: 15 Class constants: 7
  • 103. PDepend
  • 104. PDepend By Manuel Pichler (Also German)
  • 105. PDepend By Manuel Pichler (Also German) Like PHPLOC, But Granular
  • 106. PDepend By Manuel Pichler (Also German) Like PHPLOC, But Granular Lower Level Analysis
  • 107. Fanout: Describes Outward Dependencies - Describes Dependence on Other Classes ANDC: Average Num of Derived Classes - Describes How Much Inheritance Is Used AHH: Average Hiearchy Height - Describes How Deep Of Inheritance Is Used
  • 108. PHPMD (Mess Detector)
  • 109. PHPMD By Manuel Pichler (German)
  • 110. PHPMD By Manuel Pichler (German) Finds "Messy" Parts Of Code
  • 111. PHPMD By Manuel Pichler (German) Finds "Messy" Parts Of Code Finds Rule Violations
  • 112. PHPMD Rules CodeSize - (CC, NPath, Number of Methods, Size of Methods, etc) Design - (Eval, Goto, Exit(), Inheritance Depth) Naming - (Short names, Inconsistent Names) Unused Code Controversial - (Superglobal Access, Naming Conventions)
  • 113. Prevent Complex Code From Even Getting In!
  • 114. By Themselves Useful
  • 115. Over Time
  • 116. Over Time Invaluable
  • 117. Jenkins-PHP jenkins-php.org
  • 118. Sonar SonarSource.Com
  • 119. Insight insight.sensiolabs.com
  • 120. Time For Some Fun!
  • 121. Drupal 8.x Branch Non-Comment Lines Of Code
  • 122. Drupal 8.x Branch Number Of Classes
  • 123. Drupal 8.x Branch Cyclomatic Complexity Per Method
  • 124. Drupal 8.x Branch Cyclomatic Complexity Per Line
  • 125. Drupal 8.x Branch
  • 126. One More Thing To Keep In Mind
  • 127. Do Not Rely Solely On These Numbers
  • 128. Instead, Try To Understand At The Bigger Picture
  • 129. Anthony Ferrara @ircmaxell me@ircmaxell.com blog.ircmaxell.com github.com/ircmaxell youtube.com/ircmaxell