Upcoming SlideShare
×

Development By The Numbers - ConFoo Edition

1,431 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
2 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Be the first to comment

Views
Total views
1,431
On SlideShare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
13
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