Marty Andrews

artful code

Tuesday, February 27, 2007

March Design Improvement EAT Workshop

Places are filling up fast for the March Desgn Improvement workshop that I'm running under the Cogent Consulting Easy Access Training program on March 24th. If you're interested in attending, get your bids in quick.

Saturday, February 24, 2007

How many tests do you need?

The number of tests you need for your system depends on how complex it is. Obvious, right? The tricky part is knowing how to measure that. There are a couple of good mathematical definitions that can help.

The Cyclomatic Complexity of a method is the number of linearly independent paths through a program's source code. This means that the Cyclomatic Complexity of a method is the minimum number of unit tests needed to test every path in a method.

Take this piece of code as an example:

public static String getFormattedName(String givenName, String middleName, String surname) {if (givenName != null) {givenName = givenName.trim();} else {givenName = "";}if (middleName != null) {middleName = middleName.trim();} else {middleName = "";}if (surname != null) {surname = surname.trim();} else {surname = "";}return givenName + " " + middleName + " " + surname;}

Every method starts out with a default Cyclomatic Complexity of one. The complexity is then increased by one for every linearly independent path through that method. In this case, each if statement in the method represents an extra path. So the total Cyclomatic Complexity for the method is four.

In other words, if you were writing tests for this method, you should write at least four of them.

The NPath Complexity of a method is the number of acyclic execution paths through that method. This means that the NPath Complexity basically represents all of the combinations of paths possible through a method, and is an upper bound on the number of tests you need to write for a method.

Lets use the same example code again.

Every method starts out with a default NPath Complexity of one. The complexity is then increased by one for every nested conditional loop, and multiplied by two for every parallel conditional loop. In this case, the method starts out with a complexity of one. It is multiplied by two at the first if block, bringing it up to two. It is multiplied by two again at the second if block, bringing it up to four. It is multiplied by two yet again at the last if block, bringing it up to eight.

In other words, if you were writing tests for this method, you should write up to eight of them.

So the number of tests you need to write is:

Cyclomatic Complexity <= Number of Tests <= NPath Complexity

The hard part now is to try and calculate what your complexity is. Fortunately, Complexian can do that for you.

Tuesday, February 20, 2007

Mile high code

On a flight from Melbourne to Newcastle today, I built some support for cyclomatic complexity into Complexian. It's not exposed via the Ant task or the main method yet, but the internals is working fine. I was pretty satisfied with the results of 45 minutes worth of coding.

Kent Beck and Erich Gamma famously wrote JUnit together on a plane trip too. There's something about the confined space and lack of other options (like phones for example) that causes you to focus on the task at hand. I wonder how much value you could get out of sending some members of your team on random flights together purely so they could pair on some interesting code.

Do you have any mile high code that you've created?

Saturday, February 10, 2007

Complexian. Simian's little brother.

With a bit of moral support from Simon Harris, the author of Simian, I've put together a tool called Complexian. It measures NPath complexity in your Java code, and warns you if it gets too high. The internals have been born from the same seeds of design as Simian, so it runs blindingly fast.

The NPath complexity of your code is exactly the number of unit tests required to get complete coverage of it. Complexian exists to measure the NPath complexity of your code and to warn you when it gets too high. Keeping the number low means that you can cover many more of the paths through your system with unit tests. That can save valuable time and money as projects get bigger and go for longer periods of time.

You can use Checkstyle already to check NPath complexity, but here's a few reasons you might prefer to use Complexian.

  1. Its significantly faster. Complexian can check the 1.2 million shared lines of code in JDK1.5 in under 15 seconds.
  2. Output is ordered so you see the “worst” offenders more obviously.
  3. You get summary of the total system, and how offensive the violations are in relation to it.
  4. Checkstyle has an overflow bug in it, so you don’t get the real story. (we’ve submitted a patch though, so this will go away eventually).

The most important reason for me is that complexity is treated like a second class citizen when its bundled in with other checkstyle checks. Too many times have I seen either the specific check turned off, or checkstyle itself turned off because developers didn’t like some formatting rule. Its important enough to me that I want that decision to be much more obvious, and treated with more consideration. If producing a tool that deals with the issue directly helps to highlight it, then I'm happy with the outcome.

You can see more details about Complexian and download it from the resources section of this site. Please send any feedback you have to me.

Friday, February 9, 2007

Exception handling rules of thumb

  1. Put your try/catch block around the smallest set of code that you can.
  2. Catch the most specific exception that you can.
  3. Interestingly, most applications should have one place in the system that completely violates both of these rules. It's the last line of defence to protect your users from whatever horrible things try to escape from inside your code.