Graphinder – TDD and starting from red


When starting a project for Daj sie poznac 2016 challenge, I’ve decided that I not only want to learn new technologies, but I also want to work my way for being a better developer. One of best ways of doing so is embracing a process of Test Driven Development in your everyday work. But what TDD truly means? Well, sure most of us test many functionalities of our systems, but way too often business code is what comes first, not tests. In TDD, it’s quite the opposite.

All code is guilty

That is hell of a statement but, yeah… If we want to go all-in TDD (do we?), we’d need to assume all code is guilty of being buggy. Having that in mind, we are set free from assumption that, quoting:

There is no way this can break/become null/enter invalid state/put your bug in here.

Even if above is true for current state of the project, we cannot be sure that it will become obsolete when solution evolves and code changes. But that actually does not apply to TDD per se, but to testing code in general.

TDD way of doing things

Test Driven Development says, that everything should be driven by writing tests. And what is essential is to write them first.

Typical development would look like this:

  • Request for functionality
  • Developer writes an automated unit tests for desired functionality, that right now doesn’t exist – Going RED
  • Developer writes minimal functional code that passes written previously tests – Going GREEN
  • Developer refactors written previously code to meet desired standards (if not already met)

That’s a general idea behind TDD, but I came to think of my way of doing TDD, with some flavor of BDD (Behavior Driven Development) and defining contracts first.

My way of thinking about TDD

What I really hate about TDD is that starting from RED often means does not compile at the very start.
What I love about TDD is that it’s a great start point for defining contracts for functionalities.
In the end I’ve naturally adopted parts of TDD that suited me best (entire workflow actually) but I’ve also introduced few parts that are known from either SOLID principles or Behaviour Driven Development.

My actual workflow looks like this:

  • Request for functionality
  • Developer writes/updates an interface, that defines required functionalities
  • Developer writes/updates a shallow class that simply implements mentioned interface without implementing any functionality (methods throw NotImplementedException instead of providing logic, properties are never set etc.)
  • Developer writes an automated unit tests for desired functionality, that now exists but throws exceptions – Going RED but compiling(!)
  • Developer writes minimal functional code that passes written previously tests – Going GREEN
  • Developer refactors written previously code to meet desired standards (if not already met)

Now, as you can see, I’ve added two more steps to general TDD workflow, so that even before writing any unit test, I think of putting functionality it tests in my interface, so that a contract is defined.
A great pro of this approach is that I actually decouple my code while doing TDD at same time. It also makes much more easier to visualize behavior of such class, when we have written it down as actual interface-based contract.
Now I will have code that compiles but simply fails – that is true starting from red for me. Now if I simply implement interface without writing any logic, I will keep on failing the tests but on exceptions thrown on particular method of implementation.
Starting from now on, any functionality that I’ll write in my actual implementation will gradually turn my tests from red to green.

Heresy you say? Figures.

Leave a Reply

Your email address will not be published. Required fields are marked *