Wednesday, September 16, 2009

The decision making triangle

As an avid agilist, I maintain that the manager should do little more than putting the following three powers together.
* The techie.
* The funding.
* The customer.

These are the three roles to any "go"/"no-go" decision making on wether or not a particular technical endeavour is worthwhile.

The "funding" is simply someone who is able to decide cost against benefit. The financial backbone for a particular push within your portfolio is often quite obfuscated in a large organization. When you no longer produce bang for the buck, you stop.

The "customer" is simply the someone who can make a decision on a satsifactory solution to any given marketable feature. The customer represents the totality of the demands. In some cases, being an internal customer that is able to map external requirements to internal technical achievable backlog items is a true assett.
A good customer is hard to come by.

Together, the two can decide on where the efforts can give the most value.

The techie translates solution proposals into estimates.


The main discipline between these three is to identify the MMF's (minimum marketable features) that will individually add to the value of the product. It is sometimes hard for a customer to see that his problem is not an irreduceable all-or-nothing deal.
Again, consider the value of a good customer.

The customer is rarely an external person. When deciding on these issues, there should be as little vested interests (and politics) as possible. An external customer is likely to play up his requirements, is unlikely to be willing to vouch satisfaction at the drawing board and various scopes are subject to contract negotiations.

On small projects, one person can have all these hats.
On large projects, the "customer" can have a full time team of three people behind him doing nothing but mapping classification requirements to the proposed features.

Since the development departments are mostly techies, the two other roles are likely to suffer. Especially the customer part. We have many products where it is unclear who demanded what, and in what manner we fulfill certain requirements.

Every agilist should appreciate a customer who can think on his/her feet.

Friday, September 4, 2009

TDD nails it

Introduction

Imagine yourself TDD'ing a thermostat controlling a heater. Your first unit test is to set the temperatures in the fake thermometer as well as the Thermostat object, which is the unit under test, and to verify that it actually starts the heater.

Now, in the production code, a TDD beginner will find it tempting to check the temperature and then start the heater. However, the correct thing is to not check the thermometer, but just start the heater regardless of input. This is because this is all that is required to pass the first test. You don't need to check the thermometer before you have a test that would fail if you didn't check the thermometer.

If the TDD beginner followed through with his gut feeling and implemented the check right away and then proceeded to the next feature he would be able to remove the thermometer check, introducing a bug in his software, without any tests failing.

Thus removing the premise to safely refactor and changing without breaking.


TDD nails it.

Now, if you were using hammer and nails to fix a piece of wood (say, a board) in place, a novice could be equally "tempted" to hold the board in place and then just hit a nail in its center before moving on.

This would look all well and good until the forces started acting upon it, in which case the board would quite likely shift out of place.

Now, let us pretend that a piece of functionality is a board and that unit tests are nails.

By using just a single nail, both the piece of functionality and the board would seemingly be held in place by nails, but in reality the real upkeeper for both is friction. Friction on wood surface and friction in the code base. Without neither being be nailed in place.

When I implement a piece of functionality I certainly hope to having "nailed it"!

Thursday, September 3, 2009

"As simply as possible"

Yesterday, I held an internal TDD Introduction workshop for about 10 developers.

I had no slides, just winging it using VS2008 on a projector. And using the whiteboard.

The workshop was in two parts.
1. The common calculator that eventually become string based requiring a tokenizer. This is to push the Red-Green-Refactor envelope. I know : pretty boring, but you want to put the emphasis on the tight cycle of TDD.

2. A case with external dependencies.
The specific use case was a HVAC controller. It starts off as a simple thermostat to control a cooling fan, but evolves to a full fledged HVAC controller.
People discover that the API of a thermostat is principally different than the HVAC controller. For example, "Desired temperature" can be a single number in a thermostat, whereas the HVAC controller needs a desired temperature with an upper and lower limit. The pattern geeks may argue that the HVAC controller is actually two thermostats working in opposites (one for "cold", one for "heat"), which certainly makes for some interesting programming.

The three immediate takeaway benefits are:
* TDD forces you to think about your interface. And working in pairs produces some fruitful debate at a very early stage. Paradoxically, people suddenly find themselves unable to express their use cases against their own API (and then they start blaming me).

* They discover that there is a "secret" dependency on time. One dependency driving requirement is that the airfan should run for two minutes after the furnace has been switched off. Hopefully they'll muck around with DateTime static helpers before realizing that time must be controlled from the tests.

* The manual mocks versus isolation frameworks (Moq). The initial test cases make for slim manual fakes, but the Moq syntax is usually heartly received.

We only had half a day, which went by in the blink of an eye, but I think that we ran into many of the typical subjects.
There certainly is stuff that is hard to get even in the simple world of TDD. We met some speed bumps when we crossed the following:

Problem 1: Lambda expressions.
I have opted for our group to go for Moq as the isolation framework of choice. This is because of the crisp syntax and a lot of sense and intellisense. The most noted objection against Moq is that it makes heavy use of Lambda expressions and therefore is only available in the .NET 3.5. However, that is no concern for us.
We had some MFC programmers in the workshop. Even seasoned and capable programmers are visibly in pain when they try to wrap their heads around Lambda expressions. I wanted to showcase the evolution of bamed method -> Anonymous method -> Lambda, but I messed up the syntax for anonymous method and we were too pressed for time to google it.


Problem 2: "As simply as possible".
However simple as it may sound, this rule is all but simple if you start going down the road creating the wrong kind of simplicity. The TDD dogmatic anecdote is that you shall make a test pass in a manner that is as simple as possible.
This is to make sure that the unit tests enforce the functionality of the production code and that the tests truly drive the development process.

Just a week ago, I was attending TDD Masters class by Roy Osherove. I think that I grocked the concept of simplicity on the second day.

In my dependency use case, the first MMF is to make the controller start the FAN if the THERMOMETER shows a higher temperature than the desired temperature which you have set against the API of the HVAC controller instance.
Now, what exactly does simplicity mean? What should be the first test?

Does it mean to not interact with the mocked FAN?
Does it mean to not interact with the mocked THERMOMETER?
Why would it have dependencies at all? Can't you just put a temperature in and the ask it if wants to start the fan?

This started to take the form of a dug-in debate in the class, which I had to cut off.

I think that there is an important distinction to be made here. You do not program unit tests that you do not intend to make obsolete at a later time. Although the unit tests only run a concrete scenario testing a narrow case, they should still execute and pass against the final product three months from now. You still need to express the complete scenario against what you, at the time of writing, expect to become the final library API for that use case.
If you program against getters and setters and the getters only return true, you are not producing value as you plan to both throw away both the unit test and the production code that made it pass. You are also bestowing a legacy API on a brand new component.


I solve the problem as follows in my very first unit test: I create a mock fan and a mock thermometer (with a temperature), pass them both to the controller as constructor arguments and expect the fan to have been attempted to turned on.
This may seem like an advanced use case, but I think it is as simple as it can be.

People in the TDD domain also argue that you should start with constructor checks. At this point, I am not actually sure if it makes sense to be able to new up an controller without arguments, so I am actually forgoing that for the moment. If a later use case starts by newing up an empty controller, I will create a specific "IsNotNull" test.

Now, here is the correct meaning of "as simple as possible": When I confirm that the test fails, and I go into production code, I totally disregard the thermometer and I merely switch the fan on. I do not even store the thermometer reference which was passed in the constructor. This leaves people speechless. The thermometer is available, why not check it? You know that you will have to check the thermometer before starting the fan in the final product.....?
The key here is to recognize the fact that I would then be able to remove the check without breaking any tests. I would be able to introduce a bug in my code without causing any tests to fail. And if that happens, what good are they? How can I safely refactor the code if the green light does not mean anything?
Everybody agrees that I need at least two test cases to "nail" the functionality in place. And I need the if. And when people realize that, they also realize that I am not doing any extra work, I am just doing it in a different order. And the order has additional benefits because I do not have the overhead of writing unit tests after having the complete functionality in the production code.

If you write unit tests after the fact, you need to change the production code in order to see them fail. It is important that you know that the unit tests you write actually can and will fail.


To sum it up: "As simply as possible" does not mean "as stupidly as possible". You still play for keeps. The production code is "work in progress", but the unit test is supposed to be done, you don't plan on revisiting it. After all, it would be tedious process with a growing amount of unit tests if you planned on rewriting the API they all consume so that they no longer describe a valid scenario.

Wednesday, September 2, 2009

Aftenpostens artikkel om nordmennene i Kongo

(This entry is in Norwegian as it comments on an ongoing debate in Norway.)

Jeg ble overrasket over dagens oppslag i Aftenposten om Tjostolv Moland og Joshua French.

Her tar en velrenommert norsk avis og supplerer "anonyme kilder" til ett åpenbart korrupt lokalt aktorat under pågående rettergang med henrettelse som mulig utfall.

Dette blir da kilder som blir benyttet i rettsprosessen som de tiltaltes forsvarer ikke har noen anledning til utfordre eller kryssutspørre.

Aftenposten forer en korrupt prosess med beleilig ikke-etterprøvbare data. Og således tar en aktiv sentral del i en prosess som ikke er Norge verdig.

For meg later dette til å være toppen av journalistisk og redaksjonell uansvarlighet. Med mulig dødelig utfall uten reell rettergang.

Navnene på journalistene, Thomas Hubert og Sveinung Berg Berntzrød, har iallfall brent seg inn på min netthinne. Håper de er såpass sikre på sine kilder at de er beredt til å inntre som aktor, jury og bøddel.


Jeg så også tendenser til dette under narkosaken i Bolivia hvor pressen ikke har vett til å beskytte folk mot seg selv. Selv om de tiltalte i Bolivia-saken var "skyldige som bare f...", så var det ett tidspunkt hvor så godt som alle aviser sluttet å skrive om saken og nye "versjoner" fra opprørte og ivrige pårørende opphørte.

Sunday, August 30, 2009

My development Tools

In an average work week I use:

Visual Studio 2008 Team Edition: The IDE of non-choice.

Reflector: There is no excuse for not having this if you work with anything that you haven't made yourself. And even then....

Resharper: Can't live without it. If you develop in VS2005/VS2008, professional version or higher, you should waste no time in getting this. This is a plugin which makes Visual Studio what it should have been in the first place. Microsoft is usually very slow to establish accommodation for sound development practices. And even Resharper is a wee slow for being the testrunner of choice.

NDepend: I love this tool. Have you ever wondered how to manage a large code base without actually having to read every single line of code? Then this is it. Also pretty straightforward to integrate into your build to enforce architectural constraints.

Redgate SQL toolbelt: We have a lot of stuff going around SQL Server. Even though I have database edition of Visual Studio, redgate are the ones that seem to actually have experience in the problems of managing such servers.

ANTS Profiler: Wanting to get to those hard-to-find and hard-to-reproduce performance issues? With very little overhead you can have it running. And, if you are able to reproduce it, you have it. Too many performance tools require you to predict exactly when you are going to see the problem. ANTS Profiler allows you to capture all, and then zoom in on it on the timeline.



Other stuff:
* Mindmanager. (when you just want to get those thoughts down)
* Expresso. (regex helper)
* Editpad. (notepad on steroids)
* SPX from Moodysoft: (screen grabber with redlining and visual effects)
* Zoomit. Every presenter need this when sharing desktop with a projector.

The debate is over, TDD won.

I find that I have very little to add to the words of Robert Martin (Uncle Bob).

I highly recommend people to look at the available videos of him and his talks about professionalism.

Our profession as programmers is very much immature. We have hard to accommodate accountability and transparency. We have little regard of what constitutes a true "Deliverable". And, to paraphrase Ken Schwaber, we have a very odd understand of what it means to be "done".
http://www.hanselman.com/blog/HanselminutesPodcast119WhatIsDoneWithScrumCoCreatorKenSchwaber.aspx
Basically, we like to do the algorithm, but we do not like to bridge the algorithm to the world.
A nice analogy is the difference between a hobby mechanic and a professional service business.


We put juniors in our office space and we expect them to produce.
Even a person operating the fryer at McDonalds gets some sort of apprenticeship.

We resist change. We resist being scrutinized. We resist being managed. We seldom recognize business value. We resist comparison.
We do not have objective standards or engineering principles. The only professional criticism from programmer to programmer is "that's not how I would do it".

http://www.hanselman.com/blog/HanselminutesPodcast171TheReturnOfUncleBob.aspx


But there are standards to be had. Engineering principles exist. But I sincerely do not know if you will actually appreciate them if you have no experience in the industry. I have yet to see this successfully condensed into a learning experience that mentor can bestow on apprentice. Or in the class room.

Uncle Bob has the comparison of when doctors learnt to wash their hands when walking from an autopsy to the maternity ward. It took a generation change to implement it. And the problem domain was unknown to anybody fresh out of the contemporary version of "med school". One may even argue wether or not it still was the same profession before and after knowing about germs.

Even though I don't think a serious argument still exist against Test Driven Development as a whole. It is still an immature practice which a significant part of the developer community still resist.

Without a frame of reference, it is hard to separate the community from the practices. It has become a part of the expected norm that software has bugs and that software development is an inherent financial liability.

I believe and hope that this will change.

Just fifteen years ago (being careful to pick a timeframe that excludes me), programmers were stereotyped to be socially awkward, cave dwelling magic workers with questionable antics and hygiene. Approachable only by the specially trained project manager who knew better than to hint at a questionable decision or belated milestone.
Today, most project managers are quite capable of programming in MS Excel and the sacred art of programming "magic" has unraveled.
Even though I presented a caricature strawman, something has certainly changed.

I hope that they will keep changing. That technical debt, development liability, Test Code coverage, Continuous Integration and automated deployment will be common case real life business metrics KPI's (Key Performance Indicators) for the future.


The debate is over, TDD won. Will the community inertia demand another 15 years before the change is de facto?

Skepticism and mentalism.

To me, skepticism is about observing the world and then build your knowledge.

I love the fact that outspoken atheists like Richard Dawkins have started to connect with the likes of Derren Brown. I believe James Randi has a big part of that credit. I think that this was an important pragmatic step for skepticism.

I do, however, find that fellow skeptics are less comfortable with that. For example, to me, the "placebo effect" is something wonderful that we should celebrate and try to isolate and purify.
However, my peers usually find the placebo effect (is there any other human intellectual endeavour where you decide to name an effect after the one thing that you know to be irrellevant?) to be a reason for dismissal. I strongly disagree. I dismiss pretty quick the explanations given (aura, holisticism, spiritualism, deities), but I recognize skills and recipes and I am fascinated by the mere fact that the body can heal itself (or at least: stop behaving symptomatically). If I could invoke the "placebo effect" at will (without mumbo-jumbo) I would prefer that to taking a pill against normal headache.