Measuring your code
   A talk by Nate Abele
        @nateabele

        nate.abele@gmail.com
Feedback

    http://joind.in/1601
Confession
Coercion, red bars & broken
windows
Continuous
Goal: Perfection
Or at the least, continuous
improvement
a.k.a.   (kaizen)
What people usually think
       Estimating costs
       Projecting deadlines
       Managerial BS!
Client Spec Sheet some paraphrased)
         (actual bullet points,
         Flash intro with no load time
         User account logins, password optional
         Ajax chat
         “Like Google”
...and my personal favorite


        Social network
Measurement is an essential element of
management; there is little chance of
controlling what we can not measure.
              - Wikipedia, “Software metric”
Wherefore... (WTF) ?
“Engineer” & “architect”
Cognitive Dissonance      *


       Engineers deal with tangible, immutable
       constraints, like gravity
       The practice of developing software is
       an inherently creative discipline
                                 * Thank you, Jones
Cognitive Dissonance
       Developer constraints (scope, schedule,
       budget) potentially / often in flux
       Software is inter-related; working on one
       part changes the others
       No project is exactly the same as another
Conclusion
       It’s not useful to measure high-level,
       intangible things like whole projects
       This is where scrum comes in handy
       Instead, we can use lower-level, more
       concrete measurements
What can we measure?
Code!!
More specifically...
         Unit test coverage
         Complexity
         Speed
         Documentation
More specifically...

         Standards conformance
         Refactoration!
Backing up...
          What is a metric?
     Measurement assigns numbers based on well-
     defined meaning

       - Sometimes the environment must be
         modified

       - Special development procedures that track
       various activities       - Wikipedia (paraphrased)

          You can cheat and use booleans, too
Notes on continuous integration
        A build system
        Runs on every code commit
        Runs tests
        Reports
Metric examples
PHP Code Sniffer
       PEAR Package:
       http://pear.php.net/package/PHP_CodeSniffer



       Checks conformance of a set of files against
       a series of classes called “sniffs”
PHP Code Sniffer
$ phpcs /path/to/code/myfile.php

FILE: /path/to/code/myfile.php
------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 2 LINE(S)
------------------------------------------------------------------------
  2 | ERROR | Missing file doc comment
 47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
 51 | ERROR | Missing function doc comment
 88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
------------------------------------------------------------------------
PHP Code Sniffer
$ svn commit -m "Test" temp.php
Sending        temp.php
Transmitting file data .svn: Commit failed (details follow):
svn: 'pre-commit' hook failed with error output:

FILE: temp.php
--------------------------------------------------------------
FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------
 2 | ERROR | Missing file doc comment
--------------------------------------------------------------
This is important because things
are standardized
Measuring code complexity
       Cyclomatic complexity
         Directly measures the number of linearly
         independent paths through a program's
         source code.
         a.k.a. 1 + the number of times it branches
Measuring code complexity
  public function render() {
      $code = null;

      if (isset($this->headers['location']) && $this->status['code'] === 200) {
          $code = 302;
      }

      if (!$status = $this->status($code)) {
          throw new Exception('Invalid status code');
      }
      $this->_writeHeader($status);

      foreach ($this->headers as $name => $value) {
          $key = strtolower($name);

          if ($key == 'location') {
              $this->_writeHeader("Location: {$value}", $this->status['code']);
          } elseif ($key == 'download') {
              $this->_writeHeader('Content-Disposition: attachment; filename="' . $val
          } elseif (is_array($value)) {
              $this->_writeHeader(
                  array_map(function($v) use ($name) { return "{$name}: {$v}"; }, $val
              );
          } elseif (!is_numeric($name)) {
              $this->_writeHeader("{$name}: {$value}");
          }
      }
  }
Measuring code coverage
Measuring documentation coverage
    Check it out @   http://thechaw.com/api_generator
Measuring documentation coverage
       Check it out:
       http://thechaw.com/api_generator



       A series of rules
       Assigns weights based on docblock content
       and various docblock tags
Measuring documentation coverage
       Basic checks:
          Do doc tags exist?
          Incomplete @param tags?
          Do @param tags match actual params?
          Does it have a @link to the man page?
Profiling
Profiling
       Get timing / memory usage on every test run
       Granular, get statistics per test method
       Using continuous integration, code is profiled
       on each commit, all on a granular level
Case study
CakePHP 1.2 release cycle




1.2 alpha   1.2 beta   1.2 RC1   1.2 RC2   1.2 RC3   1.2 RC4
Metrics are your canary in the coal
mine of your development cycle
By tracking profiler stats (and other metrics),
we can see trends over time, and catch
problems before they become problems
Plus, who doesn’t like pretty graphs?
Finding things to measure
        Lithium Inspector class
        Lithium Parser class
        Based on the awesome work of Sean Coates
        http://github.com/scoates/tokalizer
Finding things to measure
Finding things to measure
Finding things to measure
Finding things to measure
Finding things to measure
In a dynamic language like PHP, this
 is a hard problem.
However, deep code introspection
 allows us to ask & answer some
very interesting questions
Project mess detection in PHPUnit
Beyond copy-paste detection & into
 pattern recognition
High-level refactoring tools
Can “good code” be quantified??
When is “good enough”... good enough?
Technical debt
Incentives and social coercion
Choose your own adventure!
Go write better code

Measuring Your Code 2.0