Test-Driven Project Initialization

Imagine you have an idea for an awesome web application. Or an desktop program or even a library in your favourite programming language do make complicated things easy. You really want to implement it, maybe you already know that it will work really well, maybe you don’t and you want to try whether you can make it work or not.

But how to start?

The first steps are easy. You make a new directory, maybe a directory structure. You create some files, such as a README.md or a LICENSE file. You create a MyGreatSoftware.MyFavouriteLanguage file and you open it in your favourite text editor or IDE.

But then you struggle and you don’t know what to do first. Let’s imagine you want to write a commandline application - do you start with the argument parsing part or do you add some backend abstraction in the first step? Do you build up a great framework around some functionality so you can use it more easily later on or do you implement functionality directly?

I had such problems, too. I started a project for a rather simple commandline application and I really didn’t know where to start. It was a ruby project, so Imy initial steps where rather clear: I installed some dependencies I wanted to use, such as an option parsing library and a commandline output helper for pretty formatted output (colored things and so on). I created the directories lib and bin - and then the file lib/app.rb (where “app” is the name of the program.

And then I failed to continue because I didn’t know what to implement first. So I ended up implementing the commandline parsing part and the backend abstractions at the same time (on different branches, of course) and it resulted in me deleting the project because things got complicated.

Then, I restarted the project and did something I’ve never done before: I started to do TDD and I started with the very first line of code.

Disclaimer: I’m not a TDD professionalist. I never had any training in TDD and I don’t even know whether I did it right. But it’s not the point whether you do TDD right or not here. The point is, you think about simple, neat pieces of code with a lot more focus. You try to imaging what explicit feature you want to have. For example your test says something like this:

If I pass an argument --update a File ~/.app_timestamp gets the current time is appended.

That’s a really really compact thing and you can implement this in one single line of Ruby. And that’s exactly my point. You start implementing things without building layers and layers of abstraction and losing yourself in the codebase you created yourself for not losing track of things.

I learned that writing tests and implementing just the very functionality that makes the test succeed helps me a damn lot to focus on the functionality I want to build rather than building layers and layers and afterwards having a kind of framework which does nothing (and is mostly even too complicated to use).

Of course, after implementing things you can clean up your codebase and refactor things, so the abstraction layers will be created at some point. But that’s after the features have been implemented. And a damn great bonus: You have tests which are there to ensure you don’t break your functionality by refactoring and making yourself happier with the codebase.

So that’s what I call Test-Driven Project Initialization. You don’t need to perform perfect TDD and stick to it all the time. You don’t need to test every aspect of your functionality. The tests are there to keep you focused on the functionality, not to ensure there are no bugs. Of course, that’s a neat side effect and you can continue and extend your test cases later on to find bugs. But for Test-Driven Project Initialization it is not the point to find bugs.