Transcription
DevelopmentBy The Numbers
We Are Going ToMeasure Complexity
Why Should We CareAbout Complexity?
"The Central Enemy OfReliability is Complexity"- Geer et al.
Complexity AndQuality Are StronglyRelated
Basic Metrics
CyclomaticComplexity
Cyclomatic ComplexityNumber Of"Decision Points"In A Routine
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}4
SimpleRight?
Cyclomatic Complexity(Single Method)1 - 4: Low Complexity5 - 7: Moderate Complexity8 - 10: High Complexity11 : Very High Complexity
Cyclomatic Complexity(Average Per Method)1 - 2:2 - 4:4 - 6:6 :Low ComplexityModerate ComplexityHigh ComplexityVery High Complexity
Compare:Average CC per MethodWordpress:6.28Drupal 7:3.02Drupal 8:2.10Symfony 2:1.81Zend Framework 2: 2.62Laravel:1.79
Cyclomatic Complexity(Average Per Line Of Code).01 - .05:.05 - .10:.10 - .15:.15 :Low ComplexityModerate ComplexityHigh ComplexityVery High Complexity
Compare:Average CC per LOCWordpress:0.20Drupal 7:0.04Drupal 8:0.07Symfony 2:0.06Zend Framework 2: 0.10Laravel:0.07
N-PathComplexity
N-Path ComplexityNumber Of"Unique Paths"In A Routine
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}
function foo( a, b) { c 0;if ( a) { c a;} elseif ( b) { c b;}if ( a && b) { c a b;}return c;}4
They AreThe Same?
NotGenerally!
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath:
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath: 8
function foo2( a, b, c) { d 0;if ( a) { d a;}if ( b) { d b;}if ( c) { d c;}return d;}CC:4NPath: 82 (CC-1)
N-Path Complexity 16:Low Complexity17-128: Moderate Complexity129-1024: High Complexity1025 : Very High Complexity
N-Path ComplexityMinimum Number OfTests Required ToCompletely TestA Routine
N-Path Complexityentity load()CC:N-Path:
N-Path Complexityentity load()CC: 2N-Path:
Cyclomatic Complexity1 - 4: Low Complexity5 - 7: Moderate Complexity8 - 10: High Complexity11 : Very High Complexity
N-Path Complexityentity load()CC: 2N-Path: 2
N-Path Complexitydrupal http request()CC:N-Path:
N-Path Complexitydrupal http request()CC: 41N-Path:
Cyclomatic Complexity1 - 4: Low Complexity5 - 7: Moderate Complexity8 - 10: High Complexity11 : Very High Complexity
N-Path Complexitydrupal http request()CC: 41N-Path: 25,303,344,960
To Completely Testdrupal http request()At 1 Line Of Code Per TestWould Require2 TerabytesWorth Of Tests
To Completely Testdrupal http request()At 1 Line Of Code Per TestWould Require412 DVD'sWorth Of Tests
To Completely Testdrupal http request()At 1 Line Of Code Per TestWould Require670k DrupalsWorth Of Tests
And That's NotThe Worst One!
N-Path Complexitydate repeat rrule process()CC:N-Path:
N-Path Complexitydate repeat rrule process()CC: 81N-Path:
N-Path Complexitydate repeat rrule process()CC: 81N-Path: 19,781,719,256
N-Path Complexitydate repeat rrule process()CC: 81N-Path: 19,781,719,256,250,000,000,000
N-Path Complexitydate repeat rrule process()CC: 81N-Path: 19,781,719,256,250,000,000,000,000,000,000
To Completely Testdate repeat rrule process()At 1 Line Of Code Per TestWould Require336T 2009'sWorth Of Tests
To Completely Testdate repeat rrule process()At 1 Line Of Code Per TestWould Require1 Greenland Ice Cap ofmicroSD cardsWorth Of Tests
CRAP
CRAP(Change Risk Analysis Predictions)
CC Cyclomatic Complexity (method)COV Test Coverage (percent)CRAP CC (CC 2 * (1 - COV) 3)
CRAPRelates ComplexityAnd Test Coverage
CRAPIncreasing Test Coverage Lowers CRAPDecreasing Complexity Lowers CRAP
CRAPA Low Complexity MethodWith No TestsIs Good
CRAPA Low Complexity MethodWith Good TestsIs Great
CRAPA Moderate Complexity MethodWith Good TestsIs OK
CRAPA Moderate Complexity MethodWith No TestsIs CRAP
CRAP 5:5 - 15:15-30:30 :GREAT CodeAcceptable CodeEih. CodeCRAPpy Code
How Do WeApply TheseMetrics?
Sebastian pqatools.orgwww.jenkins-php.org
PHPLOC
PHPLOCBy Sebastian Bergmann
PHPLOCBy Sebastian BergmannCommand Line Tool
PHPLOCBy Sebastian BergmannCommand Line ToolSummarizes An EntireCodebase
phploc path/to/Drupal7/Directories: 73Files:180Lines of Code (LOC):63347Cyclomatic Complexity / Lines of Code: 0.04Comment Lines of Code (CLOC):19321Non-Comment Lines of Code (NCLOC):44026
Namespaces: 0Interfaces: 1Traits:0Classes:38Abstract: 2 (5.26%)Concrete: 36 (94.74%)Average Class Length (NCLOC): 197
Methods:433Scope:Non-Static: 378 (87.30%)Static:55 (12.70%)Visibility:Public:255 (58.89%)Non-Public: 178 (41.11%)Average Method Length (NCLOC): 17Cyclomatic Complexity / Number of Methods: 3.02Anonymous Functions:0Functions:521Constants:22Global constants: 15Class constants:7
PDepend
PDependBy Manuel Pichler(Also German)
PDependBy Manuel Pichler(Also German)Like PHPLOC, But Granular
PDependBy Manuel Pichler(Also German)Like PHPLOC, But GranularLower Level Analysis
Fanout: Describes Outward Dependencies- Describes Dependence on Other ClassesANDC: Average Num of Derived Classes- Describes How Much Inheritance Is UsedAHH: Average Hiearchy Height- Describes How Deep Of Inheritance Is Used
PHPMD(Mess Detector)
PHPMDBy Manuel Pichler(German)
PHPMDBy Manuel Pichler(German)Finds "Messy" Parts Of Code
PHPMDBy Manuel Pichler(German)Finds "Messy" Parts Of CodeFinds Rule Violations
PHPMD RulesCodeSize- (CC, NPath, Number of Methods, Size of Methods, etc)Design- (Eval, Goto, Exit(), Inheritance Depth)Naming- (Short names, Inconsistent Names)Unused CodeControversial- (Superglobal Access, Naming Conventions)
Prevent Complex CodeFrom Even Getting In!
By ThemselvesUseful
Over Time
Over TimeInvaluable
Drupal 8.x BranchNon-Comment Lines Of Code
Drupal 8.x BranchNumber Of Classes
Drupal 8.x BranchCyclomatic Complexity Per Method
Drupal 8.x BranchCyclomatic Complexity Per Line
Drupal 8.x Branch
One More ThingTo Keep In Mind
Anthony utube.com/ircmaxell
Cyclomatic Complexity (Average Per Method) 1 - 2: Low Complexity 2 - 4: Moderate Complexity 4 - 6: High Complexity 6 : Very High Complexity