July 2006


I’ve just come back off holiday with the missus and 3 kids. It ended up being a fanastic break, but started off as a right old howler! The middle kid, India, can be nightmare and morphed into a some demonic, adult munching, seven legged monster on day one of the holiday. That same night the missus and I discussed the issues and formulated plans to improve the situation. Day two was an improvement and again that night we revised our plans. Day three was even better and so on and so forth. Happy holidays…

When I got back from holiday it suddenly dawned on me that I was applying the stuff that I do when running software projects to my homelife. Sad, but true! There are many different names for this (not my sadness), but I like the term used within Crystal Clear - Reflective Improvement. It you think of the holiday as a release, then each day was an iteration within that release. Intra-day we were doing Reactive Improvement, bascially dealing with issues as and when they arose. Inter-day, we were doing Reflective Improvement.

You need a heathly dose of both reactive and reflective improvement. With reactive improvement, you are making tactical adjustments within an iteration to steer it to a successful conclusion. However, tactical adjustments are not as effective unless they are made within the context a strategy. The strategy defines objectives and success criteria, however formal or informal you wish to make them. Moreover, the strategy needs to be made outside of an iteration so that the team can discuss the issues as if looking down on the battlefield from the highest mountain, rather from in the frontline trenches.

The sad truth is that the majority of software projects I’ve encountered, I may be unlucky, deal purely in the reactive improvement and reflect only once as an post-project post mortem exercise. What the hell use is that? If I had I done that on holiday, India would surely have completely devoured by left big toe, and heaven knows what next.  But don’t worry, I’m fine…

Over last month or so, I gave a couple of lectures on software development to students at the Poznan University of Technology(PUT), Poland. PUT is a great place and the students are (refreshingly) very keen to learn. It was the students who asked to get electronic copies! Anyway here they are.

  • The first lecture talked about the key differences between developing and delivering software
  • The second lecture built on this to convey the things you do to professionally deliver software.

For those that didn’t attend, you should be able for the follow the main flow.  If not, ping me…

Enjoy.

I’m not agile, but I have agile tendencies. I’m not test-driven, but I am a firm believer in writing tests as you develop. Treat your tests as your source code keeps you honest and on your toes. So why the post? I’m starting yet another project and I wanted to give Test Driven Development (TDD) as shot. That’’s all.

Some background. The project we have is tight. No changes there. It has a couple of releases, that we have further broken down in iterations. We are currently in the second iteration of the first release. The first iteration was to provide a live end-to-end mock up of the web site we are developing for our client. As a proponent of user-centric design, I’m keen to get the application in front of the end-user as soon as is humanly possible. As a result, and as expected, the requirements shifted quite a bit after iteration one but we, customer and us - the team - are now happy with the screen flow. Major bonus point.

Given the project is heavily database focused and it requires us to connect to legacy data, the second iteration is all about domain modelling. The technology base is comprised of all the usual suspects being Java, Spring, Log4J and WebWork as the presentation layer. My task was to take the end-to-end mock up and write the first DAO. In doing so, it would bring Hibernate to the party. So I started by writing a test.

Step 1: Create the test!

Our application has auditing requirements. Write a test to store an auditable event into the database and verify that it can be retrieved at a later date.

Status:

  • Test completed. Cannot compile code

Time Taken:

  • 3 minutes

Current feedling:

  • I’m in a dark place - this is going to take some fixing. I feel sick.

Step 2. Make the test compile

A number of classes were created such as the DAO and methods required to save and get back auditable events.
This amounted to the AuditableEventDao, the AuditableEvent POJO, an exception class to report errors and suitable documentation for these classes and interfaces.

Status:

  • Code base compiles. Test fails.

Time Taken:

  • 5 minutes

Current feeling:

  • I feel dirty. This design feels all wrong. This test driven approach has pushed me down a certain design track. I don’t like being pushed.

Step 3. Refactor

Not happy with a couple of structures so I spend some time thinking and making things a bit neater and tidied up the comments in the process. Got the tests firing up within spring.

Status:

  • Code base compiles. Test fails.

Time Taken:

  • 5 minutes

Current feeling:

  • Happier! A lot happier. I know where I’m going but still a long way from home. Time for a coffee.

Step 4. Make test succeed

This part was just plain tedious. Nasty. It was all infrastructural stuff. Getting the in-memory database running (hsqldb), writing the hbm files, configuring spring to work with hibernate, fixing the maven2 pom files, and so on. However, that said, having the test in place focussed the mind and swiftly pulled me back to the main run when i drifted off-piste experimenting with stuff.

Status:

  • Code base compiles. Test succeeds

Time Taken:

  • 15 minutes

Current feeling:

  • Pretty good. I’m out of the tunnel…but not done.

Step 5. Refactor
This was the part I enjoyed the most. The tests are succeeding and I’m tinkering with the test framework. Making things better. Removing stuff here. Adding stuff there. Running the tests to check that I haven’t dropped the ball. It’s all good stuff.

Status:

  • Code base compiles. Test succeeds. Added more tests.

Time Taken:

  • 15 minutes

Current feeling:

  • Smug. Game over. I want to write more tests…

Okay, I enjoyed myself. However, this is not the first time I’ve done this. Its just that I don’t do it all the time. More importantly, I don’t always write the test first. Will I going forward? I doubt it. But that would be the exception, rather than the rule. You can’t always develop in a TDD manner. You cannot have complete test coverage for your codebase. Any who says they have, I’d like to see it. But that doesn’t mean you cannot have a test framework that provides you with means to be make changes with confidence. For me, that’s the biggest win and the reason that we must move forward with writing more tests and if TDD helps in the battle, then I will use it where appropriate.