Life on Rails » Technological travels in Flex, Air, RIA and life in general
Imagine a beautiful autumn park, and a bald ginger man reading books and playing guitar, and doing other stuff

TDD or not TDD, that is the question

I’ve seen the light. For so long I thought I was doing TDD, I thought I was being agile, and I hate to admit it, but I wasn’t. I was trying too hard. I was thinking too much, and secretly holding to fears and misconceptions that were stopping me from realising the benefits of some of the best agile practices.

I’m not hung up or bummed out though – it was fair enough really – the project’s I was on didn’t really allow for a truly agile approach for the majority of the time. The fact is you have to breathe out before you breathe in, and I was in a situation where there was no breathing space at all.

But I eventually did get some breathing space, and a neat reading list and as fate would have it, that coincided with one of those periods that we all get as software engineers, where you get real hungry. I’m not talking raid the fridge hungry, I’m talking knowledge hunger – process hunger, efficiency hunger.

I’ve been lapping up some great stuff and it made me see where I was going wrong in a lot of areas. The biggest one I came to realise was that I wasn’t really doing TDD.

I kept trying, but I’d always buy into THE OLD LIE. You know – “it takes too long to write the test up front, I’ll just nip back later”. Recently though, I sat myself down after my latest book bout and had a word with myself.. what was stopping me from doing this?

It turns out it was actually something quite simple – it took so long for me to compile and run tests on the projects that I was in, that I had a skewed opinion of TDD. I was literally associating the amount of time it took to build and run a full testrunner (often times in excess of 800 tests) with TDD. In short I had been foolish.

I think it was the nazareen who said “if thy eye offends thee, tear it out”, which though seemingly grim, is actually good advice. And tear it out I did.

I basically came to a new understanding – this is it: The testrunner is the total suite of tests for the entire application, The testrunner is the docuemntation of the API’s of the entire application, The testrunner is ueful for regression, The testrunner is useful when building to ensure the application is in a healthy state, The testrunner actually is more and more depending on how many books you read, and how good your memory is.

One thing the testrunner is NOT however, is a harness for doing TDD.

This has been my single biggest leap in understanding of TDD. Quite simply the apps I work on are so big that building and running the entire testrunner in order to do TDD is simply unbearable.

On my last project some of us would sometimes remove all the tests from the testsuite, save 1 or 2 (remember, if thy eye offends thee – tear it out ;-) ). However, we never formalised this process – sometimes with disastourous consequences: You’d run the testrunner and find someone had deleted ALL of the tests in the app.. Looks like that build that went out might have only gone out with 1 out of 1,000 tests being run on it..

I can’t believe how obvious the answer is.. I just made a new rig – TDDRunner.mxml, and a new testsuite AllTDDTests.as. It’s really simple – each developer has their own AllTDDTests file which they keep the tests in that they need at any given time, and never check it in.

I’ve been doing this for a week now and with great results. I’m genuinely able to do TDD without any painful overhead, waiting for the compiler, or other tests, or risking deleting the testuites, or without even losing concentration. It’s a dream come true.

As I write the tests, I add them to the main testrunner, and I run this whenver I reach a mile stone (such as finishing a presentation model, or a domain model ) to ensure that regression is not caused elsehwere.

I cannot emphasize enough how great the benefits of this approach are. Myself and a couple of colleauges are literally buzzing off TDD as a result of this. It’s also much easier to sell to others who are usually closed to it.

It’s gone from barely being able to justify it to some colleagues to the point where they now have no excuse for not doing it.

Perhaps with other languages this isn’t such a problem, but with actionscript, or I suspect with any app with a large testsuite, I suspect this simple process improvement will lead to more developers practising TDD.

1and1 does it again, great hosts

Just a short note to say that I truly love the web hosts 1and1. That’s who my server is hosted with, and who is responsible for hosting all of the sites I have.

They have great dedicated server packages that are super fast, with loads of bandwidth. I actually run visualchat.co.uk on on of their dedicated servers, which has ample bandwidth for all the audio and video of the webcam chat sessions.

In short,

  • the servers are fast,
  • they got great control panels,
  • the support is actually really good, both written, and on the phone,
  • the bandwidth is phenomenal,
  • you get free ftp backup with each dedicated server,
  • they never go down.

They really are great – I strongly recommend them… However, I’m not writing because of that – I’m writing to let you know that they have exceeded my expectations again:

In September 2007 I took up a new server package, a beefed up dedicated server, that came with 3 months free contract, then 18 months minimum term. Now, I was intending to migrate my existing dedicated server (contract expired) to the new server.

However, I started working for Adobe, and was so busy that I never got a chance to move the server, and therefore ended up paying for both dedicated servers. Now 1and1 get a few bad reviews for locking people into contracts, but I have to say – they were great with me – I called them, explained what had happened, and they simply asked me to fax them the details.

The server is now cancelled: Including the 18 month contract! Yep! they just let me back out of it, by being reasonable and human about it all – so next time someone tells you that they are monsters, and hold people in to contracts, I suggest you ask them how they spoke to their staff, and how they treated them – I know other people who have been rude, and they get what they give..

I don’t know any other host that would do this – I can definitely tell you 3 other hosts that wont budge at all on these matters (though I don’t want to name them)...

BTW, I’m not an affiliate – I haven’t joined their program, so I’m genuinely objective – check them out if you want dedicated servers- for any small-medium scale project (read as, don’t need a server farm and fail over), they’re great!

Handling user blocks in mysql (or how I learned about "on duplicate key")

This will no doubt be old hat to mysql and postgres users, but I came from sql server..

I was working on a site called visualchat.co.uk which allows users to chat to one another – and, as you might expect we get our fair share of nob ends.. As such we give our users the ability to block one another.

I recently made another version of this site and moved the entire stack from asp.net, sql server flashcom, to mysql, ruby on rails and red5, I was pleasantly surprised when it came to implementing the blocks in mysql.

I store the blocks in a table with the following field:

id, user_id, to_user_id, block_type

All of these are integers.

I found with mysql I can create an index on user_id and to_user_id
  1. CREATE UNIQUE INDEX user_block ON blocks(user_id, to_user_id)

Now users can change their blocks to block, or unblock individuals, and also use that integer setting to indicate if they want to turn a clean chat filter on or off, as these might change several times in a users history, I can’t (in sql server anyway) do a straight update, I need to do a select, and then update or insert depending if the value is present.

I optimised that in sql server using temp tables, but I always was unhappy with the way it was implemented. When I moved to mysql I found that it has this great feature called ON DUPLICATE KEY UPDATE.

It allows you to insert into a table, and when an insert would cause a duplicate key, update the existing row. Now this is just what I wanted – I could now do code like:

INSERT INTO blocks (user_id, to_user_id, block_type) VALUES (1,2,6) ON DUPLICATE KEY UPDATE block_type=7;

This has made my life so much easier, I can now get my chat server to dump all of the changed block settings into a given session into a temp table and use this niffty command to persist the blocks!

I’m sure I’ll be using this again in the future too – super handy!