ThoughtWorks
code metrics & analysis
for agile projects
NEAL FORD thoughtworker / meme wrangler
ThoughtWorks
14 Wall St, Suite 2019, New York, NY 10005
[email protected]
www.nealford.com
www.thoughtworks.com
memeagora.blogspot.com
ThoughtWorks
ThoughtWorks
what i cover
why use metrics?
metrics + agility
analysis tools
code metrics & tools
the hawthorne effect
ThoughtWorks
the hawthorne effect
measure and let it be known that
you are measuring
software “engineering”
“What is Software Design?
jack reeves
1992, c++ journal
compares
“traditional”
engineering with
software engineering
agility + metrics
changing
code quality
requirements
adaptable to
refactorability
change
metrics help you
measure this if...
vs
“wow, our code sucks” part of continuous integration
verified on iteration
evaluation of other code
boundaries
ThoughtWorks
what are we trying to
avoid?
lava
flow
anti-
pattern
Analysis
byte-code analysis:
findbugs
bug categories
correctness
probable bug
bad practice
violation of recommended & essential
coding practice
dodgy
confusing, anomalous, written poorly
source analysis & pmd
pmd targets
possible bugs empty try/catch blocks
unused local variables
dead code parameters
private variables
suboptimal code wasteful string usage
overcomplicated expressions
duplicate code reuse via copy/paste
code metrics
from another era
tons of useful
information...
about mainframe
code
mostly outdated
unit tests & coverage
JVM
code coverage
Instrumented
class files
Original Instrumentation
class files Processor
coverage runtime
Coverage Report
doesn’t tell you if you code is right...
...but at least tells you it’s been touched
justifying coverage
1. instrument your code
2. give it to quality assurance
3. tell them to run every test
lucky to get 75%
4. produce coverage report
5. weep profusely
useful
code
metrics
ThoughtWorks
kloc
cyclomatic complexity
measures complexity of a function
V(G)= e - n + 2
V(G) = cyclomatic complexity of G
e= # edges
n= # of nodes
int max (int a, int b){
int max = a;
if (a < b) {
max = b;
}
return max;
}
start
1 if (c1)
1
2 f1() 3 f2()
4
4
3
if (c2)
5 6
nodes
5 f3() 6 f4()
edges
7
8
7
end
npath complexity
# of possible execution paths through a
function
takes into account the nesting of conditional
statements and multi-part boolean expressions
available through checkstyle
# of tests to completely test a method
ThoughtWorks
chidamber & kemerer
object-oriented metrics
shyam r chidamber
chris f kemerer
easy but useless very useful
easy (but useless)
dit depth of inheritance tree # levels of inheritance
noc number of children # immediate descendants
number of public
npm # public methods in class
methods
very useful
weighted methods/
wmc ∑ of cyclomatic complexity
class
# of methods executed due to
rfc response for class
method call
∑ of sets of methods not shared
lcom lack of cohesion
via sharing fields
cbo/ ∑ of other classes this class uses
efferent couplings
ce (outgoing calls)
∑ of how many other classes
ca afferent couplings
use this class (incoming calls)
efferent/afferent
couplings
ce measures ca measures
extrovertedness introvertedness
ckjm
open source tool to run c&k metrics
produces text or xml output
simple to the extreme, but fast
running ckjm
run ckjm on a single class:
java -jar /usr/local/lib/ckjm-1.5.jar build/classes/gr/spinellis/ckjm/Foo.class
run ckjm on a single class from a jar file:
java -jar /usr/local/lib/ckjm.jar 'ant-jai.jar
org/apache/tools/ant/types/optional/image/Text.class'
run ckjm on classes in a jar file:
find build -name '*.class' -print | java -jar /usr/local/lib/ckjm.jar
jdepend
jdepend
traverses class file directories and...
...generates design quality metrics for each
package
package based metrics
coarse grained
jdepend metrics
∑ of other packages
ce efferent couplings upon which this
package depends
∑ of packages that
ca afferent couplings depend on this
package
instability
ce
i=
(ce + ca)
indicator of the package’s resilience to change
i = 0: a completely stable package
i = 1: a completely instable package
abstractness
! abstract
a=
! classes
a = 0: a completely concrete package
a = 1: a completely abstract package
distance from main
sequence
perpendicular distance of a package from the
idealized line a + i = 1
squarely on the main sequence => optimally
balanced
ideal packages are either
completely abstract & stable (x=0, y=1)
completely concrete and instable (x=1, y=0)
distance from main
sequence
dependency constraint
dependency cycle
project
dependent
main
sequence
distance
test
Code Change Risk
Analyzer & Predictor
for Java
crap4j
3
(
crap(m) = comp(m)2 x 1 -
cov(m)
100
) + comp(m)
where:
comp(m) = cyclomatic complexity
cov(m) = line code coverage
for a given method, the crap # ranges from
1 to ∞
crap threshold = 30
crap threshold
% code coverage required to
cyclomatic complexity
be below CRAP threshold
0-5 0%
10 42%
15 57%
20 71%
25 80%
30 100%
31+ Always CRAPpy
ThoughtWorks
crap4j
eclipse plug-in reports crap score &
crap load
estimate of total
work required to
address crappy
methods
“A project dedicated to making code
metrics so widely understood, valuable, and
simple that their use becomes ubiquitous,
thus raising the quality of software across
the industry.”
panopticode parts
code coverage with emma
1-line change to switch to cobertura
checkstyle
1-line switch for custom rule sets
jdepend
javancss
volatility
panopticode parts
code duplication using simian
panopticode aggregator
panopticode reports
treemaps
complexity
code coverage
ThoughtWorks
information radiators
inform motivate
transparency
shame
bond encourage
aggregate metrics
cc over time
metrics + agility
wire metrics & analysis into
continuous integration
manually check often
discuss on iteration boundaries
fail the build with
xpath expressions & plugins
jdepend-like unit tests
ThoughtWorks
questions?
please fill out the session evaluations
slides & samples available at nealford.com
NEAL FORD thoughtworker / meme wrangler
ThoughtWorks
14 Wall St, Suite 2019, New York, NY 10005
This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 2.5 License. [email protected]
www.nealford.com
www.thoughtworks.com
http://creativecommons.org/licenses/by-nc-sa/2.5/ memeagora.blogspot.com
ThoughtWorks
resources
Jack Reeves What is Software Design?
http://www.bleading-edge.com/Publications/C++Journal/Cpjour2.htm
findbugs
http://findbugs.sourceforge.net/
pmd/cpd
http://pmd.sourceforge.net/
ckjm
http://www.spinellis.gr/sw/ckjm/doc/indexw.html
jdepend
http://clarkware.com/software/JDepend.html
ThoughtWorks
resources
code coverage tools for java:
cobertura - http://cobertura.sourceforge.net/
emma - http://emma.sourceforge.net/
clover - http://www.atlassian.com/software/clover/
code coverage tools for ruby:
rcov - http://eigenclass.org/hiki.rb?rcov
railscov - http://svn.codahale.com/rails_rcov
crap4j
http://www.junitfactory.com/articles/crap4j/
panopticode
http://www.panopticode.org/
ThoughtWorks
resources
checkstyle
http://checkstyle.sourceforge.net/index.html