Tuesday, May 12, 2009

Automated Code Governance

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/automated_code_governance.htm]

There are lots of ways for a tech-lead to encourage standardization. However, any policy that requires manual enforcement will continually be facing an uphill battle. The problem with the human enforcer is that:

  1. Enforcing policy is seen as being the "bad guy", and no-one wants to always be the bad guy
  2. The human will not have time - they'll be pulled onto other features
  3. The human will be accused of "ivory tower" antics that just slows down real work
  4. The human cannot possibly monitor everyone's code every day

The optimal way is to have an automated build policy as part of your continuous integration. This policy could check for many objective metrics, such as (DISCLAIMER: I haven't personally implemented all of these yet - it's just a brainstorm based on various research):

  • Code Coverage - Enforces developers to write unit tests by demanding that the tests provide X code coverage.
  • Code metrics (like NDepend) - Runs static metrics like LineCount (discourages large methods that have multiple responsibilities) and cyclomatic code complexity (including checks for dependencies, which is often then #1 culprit that prevents testability).
  • Code duplication (like Simian) - Encourages refactoring by checking for chunks of duplicate code. Ideally, this covers not just C#, but all languages like HTML, JS, and SQL.
  • Static code analysis (like FxCop) - Runs static rules to check for bad or risky code, kind of like compiler warnings on steroids.
  • Stored Procedure scans - Creates a test database, and runs all the stored procs to check their query execution plan for performance bottlenecks (like table or index scans), or too many dependencies.

While policies sound cool, in the trenches, many devs view them as just a nuisance that slows down "real" work. Here are some problems to anticipate:

  • Devs don't want to do it - it's not fun to write high-quality code.
  • Devs complaining that they don't have time
  • Management pulling the rug out from under you (they don't have time, or they don't want to be the "bad" guy)
  • Makes build take too long

Given these types of problems, here are ideas to minimize any riots as you try to roll these out.

  • Set up policy first - without it failing the build yet, so everyone can see results for a few weeks.
  • Ensure that people can run all policy checks locally first, and verify that they pass locally.
  • Create an exclude list so any developer can register exceptions.
  • Grandfather all existing code by using this exclude list.
  • Minimize the scope of what is checked (start with just 1 core assembly, and gradually expand to others).
  • Roll out 1 policy at a time.
  • Ramp up your build servers. Consider a distributed build, such as using CruiseControl's project trigger feature.

No comments:

Post a Comment