May 28, 2015

The Wrong Kind of Paranoia

  —A look at const-correctness and software architecture.

I tend to be pedantic in my approach to coding C++. I like const, I declare access to data members private. A wider view is presented in The Wrong Kind of Paranoia.

I don't interpret this discussion as an argument against writing code like I do. I interpret it as a wider discussion on how important it is to look at the quality attributes you want from your architecture.

Using one example in the article, safety is a quality attribute that you want the architecture to provide and that's why you separate the code that irradiates patients from the user interface. I agree with James: programming in the small will not address this type of architectural issue.

In all, the main take away I get from James' point is that programming in the small is part of the solution but don't loose sight of the architecture. If you do, none of the const data you create will make any difference whatsoever.

May 22, 2015

Why Most Unit Testing is Waste (A Look at Test-Driven Development)

  —A look at Test-Driven Development in James O. Coplien's article on waste in unit testing.

I reviewed “Jim Coplien and Bob Martin Debate TDD”, to better understand Coplien’s position on Test-Driven Development (TDD) in “Why Most Unit Testing is Waste”.

In defining TDD, Martin states that it is infeasible for a software developer to call themselves professional if they do not practice TDD. He goes on to cite the laws of TDD:
  1. Don’t write a line of production code unit you have written a failing unit test.
  2. Do not write more of a unit test than is sufficient to fail. (Not compiling is a failure.)
  3. Do not write more production code than is sufficient to pass the currently failing unit test.
In order to properly understand Martin, it is important to understand his use of “professional”. A professional is an expert. [1] Later, Martin says that he thinks it is irresponsible for a developer to ship a line of code that has not been executed with a unit test.

Essentially, expert software developers test their work using unit tests.

Coplien’s problems with TDD are two-fold.
  1. The use of TDD without an architecture or framework.
  2. The use of TDD without an architecture or framework destroys the GUI.
Both problems have the same root cause: a poor architecture. Coplien provides examples where a lack of domain knowledge contributes to these problems. A lack of domain knowledge has no bearing on the usefulness of TDD.

TDD can be used to drive architecture. Driving architecture is one thing. Bootstrapping it is another matter entirely.

Coplien and Martin agree: do some up-front architecture, but don’t knock yourself out. Let executing code inform future decisions.

How much up-front architecture is required?

Coplien says that a 2 million line program should have constructors and destructors in place and enforce important relationships between objects and that these relationships be supported by tests. And you should have executable code for this implementation within 30 minutes.

Coplien’s tests are not unit tests. Coplien defines a unit test as an API test. It tests a subset of the state space of the API arguments. It’s a heuristic. He suggests “Design by Contract” is a better choice.

Design by Contract (DBC) ties an implementation to business requirements. TDD obfuscates this because the emphasis on unit tests can make it difficult to connect functionality to business requirements. It's not clear that the use of TDD implies causality.

Martin’s position on DBC is that he prefers unit tests tied to production code instead of contracts embedded within the production code.

Martin implies that something being used (TDD) is better than something that is not being used (DBC). I agree. Lack of use implies low utility but so does misuse. Low utility does not mean that the ideas in DBC are invalid. Unfortunately, the DBC verse TDD discussion doesn't go very far before the session ends.

This debate provides clarity on bootstrapping an architecture. Bootstrapping is hard and the transition from exploring the problem space and defining an architecture to developing executing code involves many tradeoffs. A balance is required. Perhaps poor judgement creates an imbalance that results in the use of TDD too early.

I like the notion that assertions provide a nice coupling between the semantics of the interface and the code itself. This provides a clear advantage over a separate unit test to enforce these semantics. Employing assertions for pre-,  post-condition or invariants is a clear win. However, using assertions does not eliminate the need for unit tests. Both should be used to create advantage.

[1] See Professionalism and TDD (Reprise). TDD currently plays a significant role in professional behaviour. Experts exhibit professional behaviour.

April 23, 2015

Why Most Unit Testing is Waste (An Exploration)

  —A look at James O. Coplien's article on waste in unit testing.

A team member shared a copy of "Why Most Unit Testing is Waste" by James O. Coplien. I was so impressed that I read it cover-to-cover.  Coplien identifies unit test smells that indicate waste in unit testing.  A follow-up article, “Seque” provides more insight on these ideas.

Coplien isn’t against unit testing. He’s for the intelligent use of unit testing and sees more value in the creation of tests that focus on features. This shifts the focus of the unit under test from a method to a feature.   

Focusing on features is necessary because it is the only system artifact capable of providing an explicit calling structure (or context) for the objects (and methods) it relies upon. An explicit calling structure is required to reason about the execution of a program. 

Value is tied to Lean Manufacturing and eliminating waste, including overburden and value in the form of what customers will pay for. To eliminate waste, evaluate your test mass using a criteria based upon business requirements. Focusing on Lean Manufacturing means that fewer unit tests are created and that test effort is directed at activities providing more value (feature testing).  

Coplien provides an example of Lean development using a map. It’s informative that shows how generalization introduces waste. Unit testing over generalize the map to the point where they exceed the requirements of the application. That’s waste that would be avoided if feature testing were used.

In “Seque”, Coplien argues against automation in support of continuous improvement: automation provides a one-time benefit and that to enjoy continuous improvement people need to remain involved. Another argument is autonomation and is directed at supporting the notion of testing as a heuristic activity and is part of the same argument against attempting to automate intellectual tasks. 

For other views on Coplien’s articles review of Reddit and Hacker News. Many of the links provided in the Hacker News article are insightful and the commentary a little more reasoned over that of Reddit.

The main message I get from Coplien’s articles is that good tests are the result of a focused intellectual activity directed at reducing the risk of program failure and that this activity should focus features. Use autonomation, not automation, if you want to continuously improve quality. 

2019-04-14: Replaced the link to autonomation as the original went dead.

March 25, 2015

The Mythical Man-Month (Worth Reading Again)

  —The Mythical Man-Month and the #NoEstimates debate.

The blog post “Estimates? We Don’t Need No Stinking Estimates!” was passed around my software team. It contains a reference to Frederick Brooks’ essay “The Mythical Man-Month”. As far as No Estimates is concerned, I like Mike Cohn’s view in “Estimates are Not Commitments”.

The reference to Brooks prompted me to review his essay and the wonderfully insightful wisdom contained therein. On introducing Brooks’ Law, Brooks writes:

Oversimplifying outrageously, we state Brooks’s Law: Adding manpower to a late project only makes it later.

People are often familiar with Brooks’ Law but are unaware of the other insights contained in The Mythical Man-Month.

Brooks describes an optimal schedule as one that uses as many people as there are independent tasks. He warns that one cannot obtain a workable schedule using more people or fewer months.

He tells us the man-month is a dangerous measure. It is dangerous because people and man-months are not interchangeable on most projects. It is also a poor measure of progress. Task partitioning, the cost of communication and overly optimistic estimates are important to keep in mind.

The key recommendation is to renegotiate the schedule without adding people and to do so that renegotiation needn’t happen again. This is ideal, but may not be practical because of commitments that require delivery at a specified time. For a look at what insight Brooks has to offer on schedules read Hatching a Catastrophe.

To think of Brooks’ Law in the manner oft quoted is to do a gross disservice to the wisdom within this essay. That is a point worth remembering the next time you are faced with poor effort estimates.

February 24, 2015

Nautilus Magazine

  —Nautilus is like the Economist magazine, but with a scientific bent.

I've recently subscribed to Nautilus. I liken this magazine's depth to that of the Economist but with a scientific focus.

The chief advantage of Nautilus over the Economist, if you want to call this an advantage, is that Nautilus is published quarterly. This ensures that I can usually read it cover to cover before the next issue arrives.

In addition to the low frequency of publication, the articles are engaging and well written. There are some really great ideas in the articles that are conveyed with humour and wit that make the topics all the more interesting.

(I do enjoy the Economist, I just can't absorb all of the content each week. Slow reader, I guess.)