At CITCON Europe in Brussels last week one of the sessions I enjoyed was on CRAP4J and other metrics for bad code. (I've put my notes up on the CITCON wiki.) Today Kevin reminded me that Clover has a similar metric for identifying risky code, a tag cloud that uses complexity to size the tag and the coverage level to color it. They have posted a sample using Lucene here. This is a pretty neat looking approach... but honestly? I don't really like it.
When you first look at the page, what do you see? I find it hard to make sense of. StandardizedTokenManager is the largest, but HTMLParserTokenManager is redder. And what about IndexHTML. It seems the same height as HTMLParserTokenManager but because the word is so much shorter it doesn't seem as significant. But is that right? When I switch to the quick wins tab then things are easiser to understand, but I wonder if that is just an artifact of the data. I'm not sure this approach scales to large projects where there are thousands of classes.
A tool that was mentioned at CITCON was Panopticode, and it will produce treemaps of complexity and coverage, with examples in their gallery. In many ways similar to the tag cloud from Clover but I find it a bit less distracting (though less cool looking). I also suspect is scales better than the tag cloud approach.
My favorite visualization right now -- and I'll fully admit a certain parental bias, as well as the bias of familiarity -- are the combinations of tables and histograms we have in the Agitar dashboard. The tables give me my top 10 list to take action on and the histograms give me a sense of the overall codebase. We have tables and histograms for both risk (which is the same metric as CRAP4J) and method complexity. Here's an example I created today for the Lucene code using the free JUnit Factory plug-in.
When looking at a codebase for the first time I typically scroll down to the classs and method complexity histograms. Doing that I here I get the impression that the methods are mostly reasonably sized, but there is a long tail off to the right. Looking at the table of top 10 most complex methods I see that StandardTokenizerTokenManager has a method with a complexity of 391 -- wow! That would be too much at 1/10th the size.
So there's my preference for the historgrams and tables. Not only do I find it better at highlighting the problem areas but I also find I can get an intuitive feel for the codebase by the same of the histograms. While at CITCON Steve Freeman turned me onto the work of Keith Braithwaite, and in particular his insight on the relationship between complexity and test-first. I think what Keith is on about the same things I'm after when looking at the histograms. If I see too many large methods I know something is up. If I see a lot of large classes I expect there is going to be too much entaglement.
Just for fun, the final "visualization" here is from Keith's free tool measure, which generates a table showing the linear fit to the log/log of count vs. complexity. It gives the same "feel" that you'd get from the histogram but without the ability to find the trouble cases. Run across Lucene I get:
Zipf Distribution Parameters | |
---|---|
slope magnitude | 1.48 |
intercept | 5.96 |
R-squared | 0.77 |
Prareto Distribution Parameters | |
---|---|
slope magnitude | 1.48 |
intercept | 7.64 |
R-squared | 0.96 |
While this is pretty sparse it makes for an easy comparison between lots of projects. (It also makes me wonder about extending the idea to class complexity as well.)
Posted by Jeffrey Fredrick at October 25, 2007 01:12 PM
TrackBack URL for this entry: