Tuesday, June 10, 2008

High code coverage + low cyclomatic complexity = quality code.

I have often heard and agree with the statement that 100% code coverage does not guaranty quality code. However, if you also monitor cyclomatic complexity of your code you will greatly increase the probability that it is problem free. If any method does not have 100% coverage or has cyclomatic complexity greater that 7 it should be suspect. The tool that I currently use for cyclomatic complexity is Code Monitor www.campwoodsw.com/sourcemonitor.html

Friday, January 11, 2008

Debugger Driven Development

I have just discovered a new way of doing TDD and I am calling it Debugger Driven Development.

This is how you do Debugger Driven Development.
1) Write a test which calls some method that does some complex calculation.
2) Add an assert statement with a null expected value.
3) Run the test in the debugger get the actual value returned by the method and use it for the expected value.

Debugger Driven Development is just so wrong. It does have some value for regression testing assuming your code is correct but it will cause big problems if it's incorrect. What you should do is always calculate the expected value by hand. That way if the value returned by your program matches your hand calculation their is a high probability that your code is correct. Doing Debugger Driven Development proves nothing.

Encapsulate complicated or generic code

Whenever you come across code that is more complex or generic than it needs to be try to refactor it. However it may not be possible to do this in some cases. When that happens just wrap the complex code with your own class that has the interface that you wished you had to work with.

Here is an example

The following code calls gateway.GetProducts(criteria) to return an array of products. Notice that most of the code below is just used to set up the criteria object.

ICriterion salesDateCriterion = new SalesDateCriterion(newstring[]{uploadDate.ToString()},
ICriterion prodLineIdCriterion = new ProdLineIdCriterion(new string[]
ICriterion productNoCriterion = new ProductNoCriterion(productNo.ToString(),
ICriterion[] criteria = new ICriterion[] {salesDateCriterion, prodLineIdCriterion,

IProduct[] products = gateway.GetProducts(criteria);

if (products.Length != 1 || products[0] == null)
throw new Exception("Product not found");

return products[0];

For my application I did not need the power that criteria gave me I only needed to find a single product by uploadDate, productionLineId and productNo. So I just wrapped the above code in a method called GetProduct. Now the client code now contains a single line of code that is much easier to understand.

public IProduct GetProduct(UploadDate, productionLine,productNo)

In the newly created class I also added two similar methods GetVariety and GetOrder.

public IVariety GetVariety(int varietyNo)
public IOrder GetOrder(DateTime uploadDate, int productionLineId, int productNo)