The argument against Test Driven Development

It seems that every time I listen to a software development podcast (which is often), somebody is talking up the benefits of Test Driven Development (TDD).  TDD does indeed have many advantages.  It focuses our efforts by ensuring that the code we write is written for a reason, i.e. to make a test, which has been derived from the requirements specification, pass.  This is in keeping with the YAGNI (You Ain’t Gonna Need It) principle.

TDD also allows a safety net for refactoring, to ensure that, after a refactoring, the code is no more broken than it was before the refactoring.  TDD is also likely to lead to ‘better’ code – more modular, cleaner, with less unwanted dependencies between classes.  And all of these are worthy goals, and perhaps are reasons in themselves for adopting (at least partially) the TDD process.

Where I take exception, however, is that it is somehow implied (and even stated) that TDD cannot help but ensure that the code we write will be ‘correct’.  Wikipedia states that, “Test-driven development offers more that just simple validation of correctness”, which would indicate that TDD does indeed offer validation of correctness.  But it doesn’t.  Let me illustrate the point.

I need a method that will return the square of a given integer.  That seems simple, so I write a unit test.

[Test]
public void TestThatTwoSquaredIsFour()
{
    Assert.IsTrue(Square(2) == 4);
}

Note that this is psuedo-code, but you get the idea.  Okay, let’s have a crack at writing the method to satisfy this test.  Again, Wikipedia gives us some guidance.

The next step is to write some code that will cause the test to pass… It is important that the code written is only designed to pass the test…

So, with this in mind, here is my code.

public int Square(int n)
{
    return 4;
}

This is the simplest code that I can write that will pass the test.  And the test will pass.  Since this is the case, we obviously have not specified the requirements clearly enough (through tests), so we’ll add another test.

[Test]
public void TestThatThreeSquaredIsNine()
{
    Assert.IsTrue(Square(3) == 9);
}

Our code now fails the second test, so let’s ‘fix’ the code in the simplest way possible.

public int Square(int n)
{
    if (n == 2)
        return 4;
    else
        return 9;
}

Run the tests again, and we have a nice green lawn.  But incorrect code.  We can go on adding more and more specific test cases, modify our method under test to pass those tests by using if statements or switch statements, and still have incorrect code.

How about adding a randomization aspect to the test, such as the following?

[Test]
public void TestThatSquareOfRandomNumberIsCorrect()
{
    int n = Random(1000);
    int result = n * n;

    Assert.IsTrue(Square(n) == result);
}

We now have a test that will (probably) force us to write a method which calculates a result rather than selecting from a limited range of options, but there are two problems: first, the test is overly complicated, and second, we have already written the required method inside the test!

So here’s the takeaway: Test Driven Development is a useful methodology which encourages the developer to develop only what is needed, in a testable and maintainable way.  However, it is important to realise that TDD does NOT mean that the produced code is correct in all cases – it is only correct in those cases for which specific tests exist.  As far as TDD is concerned, the code can fail in every other imaginable case.  So keep using your brain as you develop.  Allow TDD to do those things at which it excels, but don’t expect it to have the Midas Touch – or you may very well fail.

Loading forms dynamically in WPF

A friend of mine who is learning WPF recently asked me how to load forms dynamically into the panes of a tab control. Being the helpful sort I am, I wrote up a quick app that demonstrates this.

Essentially, the idea is to create the forms as UserControls, and then load these at runtime into the host control (either a TabItem or some other Content or Item control such as a Grid). Remember that for a Content Control, you would set mycontrol.Content to the new form, while an Items control can contain multiple children, so to replace the content with a form you would call mycontrol.Children.Clear(), followed by mycontrol.Children.Add(newform).

The demo app is available here.

Japan – The Last Day

I managed to find some free internet access in the departure lounge, so decided to make use of it.  I left Panasonic today at 3pm local time, and caught the train back to the hotel to pick up my baggage.  My timing was impeccable, as the airport bus was only a few short minutes from leaving as I got to the stop.  The 70-odd minute ride to the airport was quiet, and gave me a chance to try to find a word to sum up my impressions of Japan.  I think I found it – “drab”.

Now, this may be peculiar to this part of Japan (Osaka – Kyoto), but everything feels just a little gray, perhaps grimy, and yet remarkably sterile.  There is very little litter, and I never saw any graffiti at all.  Perhaps the youth of Japan are instilled with a little more respect for others and for authority here, and certainly crime is lower in Japan than back at home.  For all that, it still feels a little lifeless.

Approaching Kansai Airport near Osaka, I realised something I hadn’t picked up when I arrived – Kansai Aiport is on a man-made island (check it out on Google Maps), and is reached by a bridge about 3km long!

I arrived at the airport about 90 minutes before check in opened, and so sat down for a while before taking a walk to find some sustenance.   Much to my delight, I found … a Starbucks!!  Real coffee!!  I was so thrilled at the prospect that is was some minutes before I realised that I had lost my mobile phone.  It must have slipped out of my pocket while I was sitting down, two floors above.  Retracing my steps brought no joy – it was gone.  So, off to the info counter.  Had a phone been handed in?  “Oh, please wait while I get paperwork”.  It wasn’t until about a minute later that she pulls out my phone and says, “Is this yours?”  That phone may not be much more than a hill of beans, but it was my hill, and those were my beans!!

Anyway, I am looking forward to getting back to Oz and seeing my (in some cases sick) kids again.  It’s been a good trip, and one that has given me some good memories, but for now, I’m glad it’s over.

Japan – Days 2 to about 5

Japanese Panadol - perhaps...OK, so I lost track of how many days I’ve been here.  I’ll cover the major events and see how we go from there…  Tuesday arrived, delivering to me the worst headache I’ve had in a long time.  Of course, it would have helped if I’d brought some Panadol.  Note to self…  I spent a long day at the office (until about 6pm, to make up for the fact that I left at 4 on Monday due to a timezone issue…) nursing my head.  On the way back to the hotel, I dropped into a 7-11 style store, and spent some small amount of time trying to communicate to the man behind the checkout that my head hurt and I needed something for it.  After much effort, I eventually got something that looked kind of like what I wanted.  At least, it said “Pain / Fever Reliever” on  side – the ONLY English words on the box other than the brand.

It's Coke Jim, but not as we know itSpeaking of pain relief, the lack of good cofVarious cans...fee here has forced me to look elsewhere for my caffeine fix.  Coke is available here in all shapes and sizes – quite literally.  On the left is one sample from a vending machine.  Screw top, 300ml bottle made of… wait for it… aluminium!  They also have Coke in more ‘normal’ style cans, although a bit elongated.  These come in at least two sizes, 250ml and something larger (haven’t seen it close up).   On the right is the 250ml can, along with a couple other interesting cans in the hotel fridge: orange juice (still, not sparkling) and coffee.  Iced coffee.  Possibly black iced coffee.  Yes, this is a strange place…

Today (Thursday), I managed to take the afternoon off to slip in a bit of sight seeing.  I caught the train into Kyoto and walked down to the Imperial Palace.  For today, I’ll leave you with a smattering of images from this trip.  Enjoy.

One train has been painted with Thomas characters.  I saw it 3 times, or there is more than one like this.

One train has been painted with Thomas characters. I saw it 3 times, or there is more than one like this.

The Kamo River runs through Kyoto.

The Kamo River runs through Kyoto.

One of the gates into the Imperial Palace grounds.

One of the gates into the Imperial Palace grounds.

Inside the grounds, there are several palaces. This is one of the gates into one of the palaces.

Inside the grounds, there are several palaces. This is one of the gates into one of the palaces.

A quick panorama of the south wall of the Imperial Palace.

A quick panorama of the south wall of the Imperial Palace.

This was as close as I got to seeing the Imperial Palace proper, as I hadn't booked a tour and didn't want to argue with the guards.

This was as close as I got to seeing the Imperial Palace proper, as I hadn't booked a tour and didn't want to argue with the guards.

This tree was a bit like a Roll Up. See the next photo...

This tree was a bit like a Roll Up. See the next photo...

Yep, totally hollow.

Yep, totally hollow.

Tranquility in the palace grounds.

Tranquility in the palace grounds.

I read somewhere that you can't pump your own petrol in Japan. Notice the hoses hanging from the roof, waiting for the attendants to grab them as you pull up.

I read somewhere that you can't pump your own petrol in Japan. Notice the hoses hanging from the roof, waiting for the attendants to grab them as you pull up.

Kyoto street scene.

Kyoto street scene.

More of the Kamo River.

More of the Kamo River.

There were quite a few of these shrines dotted about the place. The swastika symbol is relevant to Buddhism, not Nazism.

There were quite a few of these shrines dotted about the place. The swastika symbol is relevant to Buddhism, not Nazism.

Back in Moriguschi, this clock is near my hotel. At certain times, the bells ring to form a tune (no doubt delightful, but I never heard it).

Back in Moriguschi, this clock is near my hotel. At certain times, the bells ring to form a tune (no doubt delightful, but I never heard it).

A close-up of the clock. Presumably the figures dance to the bells.

A close-up of the clock. Presumably the figures dance to the bells.

Near the clock is the place where plastic chairs go to die...

Near the clock is the place where plastic chairs go to die...

Japan – Day 1

Before I left Sydney I decided that Japanese youth culture and I were just not going to get along.  For a start, I prefer the top of my pants to be ABOVE my knees.  Anyway, my work was paying for me to fly to Japan for a week, so who was I to complain?

Despite being a JetStar flight, things were surprisingly comfortable for the 9 hour flight into Osaka.  Being in a wing exit row helped – I could stretch out a bit – and the personal video-on-demand unit didn’t hurt either.  I was able to watch a couple of movies that I wanted to see (“Love the Beast“, “Fast and Furious“), and was able to jump back to my childhood with a couple of episodes of “Pinky and the Brain” (“Are you pondering what I’m pondering, Pinky?”  “I think so Brain, but if you swap the ‘P’ with an ‘O’ my name would be ‘Oinky’!”).

Arriving in Osaka, I was struck by the fact that there were not one but two air bridges allocated to each terminal gate, to help load and unload quicker (or to keep first class away from cattle class), and that we didn’t walk to the baggage carousel and customs – we got on a train!  After clearing customs (the cavity search was surprisingly gentle), I was able to catch a bus for the ride out to Moriguchi (about a 70 minute ride).

The area around the hotel (Royal Pines) is not very touristy, Moriguchi being more of an industrial centre, but nevertheless I packed my camera and took to the streets in search of points of interest and food.  I wasn’t very successful in either attempt, so I present you with a view from my hotel room.  The area at lower left is the train station.

View from the hotel room window

View from the hotel room window

 

Since I had been unable to buy a power adapter in Australia, and had forgotten to get one at the Osaka airport, I used my short battery life to Skype my wife, read a chapter or two of Jeremy Clarkson’s “Don’t stop me now“, and went to bed.

Morning came.  To be honest, today has been a bit of a mad rush and I haven’t had much time to process it yet, but a few salient points stick out.

Firstly, I have decided that the Japanese wouldn’t recognise a good cup of coffee if it fell on them from the top of Mount Fuji.  The cappucino I had tonight in the hotel restaurant looked and tasted a little like frothy dishwater.  The ‘American Brew’ I had for breakfast this morning was like said dishwater after it had cleaned a good number of sushi bowls.  Still and all, it contained caffeine, and so was a necessary evil.  Interestingly, the hotel room doesn’t have coffee sachets.  Green tea and noodle cups, but no coffee.

Dinner tonight (at the aforementioned restaurant) was quite good, despite the coffee.  I ordered ‘Aussie Beef and Vegetables’, being the adventurous type.  I should have known better.  The meat was excellent, but was served on a plate of bean shoots and onion, with potato, beans, pumpkin, and some red substance with little flavour and less texture.  Could have been tofu.  Oh, and the eating implements?  Chopsticks!  How Aussie!  Well, we are a multicultural nation, are we not?

The meal was surprisingly cheap: 1500 yen for the main dish (about $18 or so).  What was less appealing was the cost of a Johnnie Walker and Coke – also 1500 yen!

Anyway, time to wrap up for the day.  I leave you with a smattering of Engrish signs hanging around the hotel room.  You’d think that it wouldn’t be hard to hire someone who speaks English natively to translate, but apparently it is.  Very hard.

Eye of Newt.  Wing of Bat.  Bugle of Fire Alarm.

Eye of Newt. Wing of Bat. Bugle of Fire Alarm.

Yes, indeed it is!  But touch not when the kettle is hot.

Yes, indeed it is! But touch not when the kettle is hot.

Honestly, who names their lamp "Off"?  And why does it need to wash?

Honestly, who names their lamp "Off"? And why does it need to wash?

31 Days of Refactoring on LosTechies

August is Refactoring Month for Sean Chambers over on LosTechies.  Some of the methods he looks at are well known, some not so much, but all are worth knowing.  Check it out at http://www.lostechies.com/blogs/sean_chambers/archive/2009/07/31/31-days-of-refactoring.aspx.

Windows 7 API Code Pack v1.0 released

My new best friend, the Windows 7 Code Pack, has been released.  From Charlie Calvert’s Community Blog:

The Windows® API Code Pack for Microsoft® .NET Framework provides support for various features of Windows 7 and previous releases of that operating system. The Code Pack has  reached version 1.0 and has been published on Code Gallery:

Here are some of the features you can from managed code using the Code Pack:

  • Windows 7 Taskbar Jump Lists, Icon Overlay, Progress Bar, Tabbed Thumbnails, and Thumbnail Toolbars.
  • Windows 7 Libraries, Known Folders, non-file system containers.
  • Windows Shell Search API support, a hierarchy of Shell Namespace entities, and Drag and Drop functionality for Shell Objects.
  • Explorer Browser Control.
  • Shell property system.
  • Windows Vista and Windows 7 Common File Dialogs, including custom controls.
  • Windows Vista and Windows 7 Task Dialogs.
  • Direct3D 11.0, Direct3D 10.1/10.0, DXGI 1.0/1.1, Direct2D 1.0, DirectWrite, Windows Imaging Component (WIC) APIs. (DirectWrite and WIC have partial support)
  • Sensor Platform APIs
  • Extended Linguistic Services APIs
  • Power Management APIs
  • Application Restart and Recovery APIs
  • Network List Manager APIs
  • Command Link control and System defined Shell icons.