Development By The Numbers - ConFoo Edition

1,316 views
1,211 views

Published 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 applications of those metrics. We'll also explore how to use these tools to gain valuable insight into legacy codebases.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,316
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
12
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Development By The Numbers - ConFoo Edition

  1. 1. Development By The Numbers
  2. 2. We Are Going To Measure Complexity
  3. 3. Why Should We Care About Complexity?
  4. 4. - Geer et al. "The Central Enemy Of Reliability is Complexity"
  5. 5. Complexity And Quality Are Strongly Related
  6. 6. Basic Metrics
  7. 7. Cyclomatic Complexity
  8. 8. Cyclomatic Complexity Number Of "Decision Points" In A Routine
  9. 9. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  10. 10. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  11. 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. 12. Simple Right?
  13. 13. Cyclomatic Complexity (Single Method) 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  14. 14. Cyclomatic Complexity (Average Per Method) 1 - 2: Low Complexity 2 - 4: Moderate Complexity 4 - 6: High Complexity 6+: Very High Complexity
  15. 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. 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. 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. 18. N-Path Complexity
  19. 19. N-Path Complexity Number Of "Unique Paths" In A Routine
  20. 20. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  21. 21. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  22. 22. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  23. 23. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  24. 24. function foo($a, $b) { $c = 0; if ($a) { $c = $a; } elseif ($b) { $c = $b; } if ($a && $b) { $c = $a + $b; } return $c; }
  25. 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. 26. They Are The Same?
  27. 27. Not Generally!
  28. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 41. N-Path Complexity <16: Low Complexity 17-128: Moderate Complexity 129-1024: High Complexity 1025+: Very High Complexity
  42. 42. N-Path Complexity Minimum Number Of Tests Required To Completely Test A Routine
  43. 43. N-Path Complexity entity_load() CC: N-Path:
  44. 44. N-Path Complexity entity_load() CC: 2 N-Path:
  45. 45. Cyclomatic Complexity 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  46. 46. N-Path Complexity entity_load() CC: 2 N-Path: 2
  47. 47. N-Path Complexity drupal_http_request() CC: N-Path:
  48. 48. N-Path Complexity drupal_http_request() CC: 41 N-Path:
  49. 49. Cyclomatic Complexity 1 - 4: Low Complexity 5 - 7: Moderate Complexity 8 - 10: High Complexity 11+: Very High Complexity
  50. 50. N-Path Complexity drupal_http_request() CC: 41 N-Path: 25,303,344,960
  51. 51. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 2 Terabytes Worth Of Tests
  52. 52. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 412 DVD's Worth Of Tests
  53. 53. To Completely Test drupal_http_request() At 1 Line Of Code Per Test Would Require 670k Drupals Worth Of Tests
  54. 54. And That's Not The Worst One!
  55. 55. N-Path Complexity _date_repeat_rrule_process() CC: N-Path:
  56. 56. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path:
  57. 57. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256
  58. 58. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256 ,250,000,000,000
  59. 59. N-Path Complexity _date_repeat_rrule_process() CC: 81 N-Path: 19,781,719,256 ,250,000,000,000 ,000,000,000
  60. 60. To Completely Test _date_repeat_rrule_process() At 1 Line Of Code Per Test Would Require 336T 2009's Worth Of Tests
  61. 61. MicroSD Card ● About 387GB / cm^3 ○ Current Density Record
  62. 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. 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. 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. 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. 66. N-Path Complexity compose_pm() CC: N-Path:
  67. 67. N-Path Complexity compose_pm() CC: 331 N-Path:
  68. 68. Because Sending Private Messages Is Hard...
  69. 69. N-Path Complexity compose_pm() CC: 331 N-Path:
  70. 70. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665
  71. 71. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028
  72. 72. N-Path Complexity compose_pm() CC: 331 N-Path: 12,334,686,665 ,165,904,892,028 ,680,955,918,269
  73. 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. 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. 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. 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. 77. To Completely Test compose_pm() At 1 Line Of Code Per Test Would Require 1B BlackHoles Worth Of Tests
  78. 78. CRAP
  79. 79. CRAP (Change Risk Analysis Predictions)
  80. 80. CC = Cyclomatic Complexity (method) COV = Test Coverage (percent) CRAP = CC + (CC^2 * (1 - COV)^3)
  81. 81. CRAP Relates Complexity And Test Coverage
  82. 82. CRAP Increasing Test Coverage Lowers CRAP Decreasing Complexity Lowers CRAP
  83. 83. CRAP A Low Complexity Method With No Tests Is Good
  84. 84. CRAP A Low Complexity Method With Good Tests Is Great
  85. 85. CRAP A Moderate Complexity Method With Good Tests Is OK
  86. 86. CRAP A Moderate Complexity Method With No Tests Is CRAP
  87. 87. CRAP < 5: GREAT Code 5 - 15: Acceptable Code 15-30: Eih... Code 30+: CRAPpy Code
  88. 88. A Word On Refactoring
  89. 89. function foo2($a, $b, $c) { $d = 0; if ($a) { $d += $a; } if ($b) { $d += $b; } if ($c) { $d += $c; } return $d; }
  90. 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. 91. Quality Is A Tradeoff Between Complexity And Bloat
  92. 92. How Do We Measure These Metrics?
  93. 93. Quiz: Only 2 Major QA Tools NOT Made By Germans What Are They?
  94. 94. PHP-CodeSniffer Behat
  95. 95. Let’s Talk Tools
  96. 96. PHPLOC
  97. 97. PHPLOC By Sebastian Bergmann
  98. 98. PHPLOC By Sebastian Bergmann Command Line Tool
  99. 99. PHPLOC By Sebastian Bergmann Command Line Tool Summarizes An Entire Codebase
  100. 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. 101. Namespaces: 0 Interfaces: 1 Traits: 0 Classes: 38 Abstract: 2 (5.26%) Concrete: 36 (94.74%) Average Class Length (NCLOC): 197
  102. 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. 103. PDepend
  104. 104. PDepend By Manuel Pichler (Also German)
  105. 105. PDepend By Manuel Pichler (Also German) Like PHPLOC, But Granular
  106. 106. PDepend By Manuel Pichler (Also German) Like PHPLOC, But Granular Lower Level Analysis
  107. 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. 108. PHPMD (Mess Detector)
  109. 109. PHPMD By Manuel Pichler (German)
  110. 110. PHPMD By Manuel Pichler (German) Finds "Messy" Parts Of Code
  111. 111. PHPMD By Manuel Pichler (German) Finds "Messy" Parts Of Code Finds Rule Violations
  112. 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. 113. Prevent Complex Code From Even Getting In!
  114. 114. By Themselves Useful
  115. 115. Over Time
  116. 116. Over Time Invaluable
  117. 117. Jenkins-PHP jenkins-php.org
  118. 118. Sonar SonarSource.Com
  119. 119. Insight insight.sensiolabs.com
  120. 120. Time For Some Fun!
  121. 121. Drupal 8.x Branch Non-Comment Lines Of Code
  122. 122. Drupal 8.x Branch Number Of Classes
  123. 123. Drupal 8.x Branch Cyclomatic Complexity Per Method
  124. 124. Drupal 8.x Branch Cyclomatic Complexity Per Line
  125. 125. Drupal 8.x Branch
  126. 126. One More Thing To Keep In Mind
  127. 127. Do Not Rely Solely On These Numbers
  128. 128. Instead, Try To Understand At The Bigger Picture
  129. 129. Anthony Ferrara @ircmaxell me@ircmaxell.com blog.ircmaxell.com github.com/ircmaxell youtube.com/ircmaxell

×