HASSANHABIB

§ 6 — Lessons Learned in the Software Industry

Uncle Bob in the Market

4 min read · chapter 6 of 32

Test Driven Development/Design (TDD) has long been established as one of the best software development methodologies. This methodology consists of writing unit tests prior to writing the actual function, then writing code to ensure each test passes. This inevitably indicates the completion of a given feature. Even though this methodology is quite effective and is considered one of the best of programming practices, it remains a narrow vision with respect to the big picture of each product and of the market/user as a whole. In modern software development teams, a typical scenario would be like this - the product owner provides a requirement with very specific acceptance criteria. The developers take on these requirements and begin by writing unit tests that verify that each feature is successful with all of its possible cases. Next, they work on writing the code that will make these tests pass (meaning the feature is complete). They will then go on to refactor the code to make it as readable as possible, so it is easy to read and maintain by other developers. The feature then goes out to the end user and often the user will make additions or changes, forcing the cycle to begin again from square one. Today this case is handled by having the developer saying, “it’s okay, we’re agile, we will take the changes, write a new user story, scrap all that we have done, and begin again!”

Look at it this way, if you were to build a house, you would begin with the overall design, having your client provide feedback and adjusting as you go, prior to installing security cameras (unit tests) and buying furniture (refactoring).

So it follows that instead of adding unit tests and refactoring before getting the actual feedback from the end user (not the product owner), why not push the testing and refactoring until after the acceptance is received. Not only does this save time and money, it keeps both the developer and the user in sync with what needs to be accomplished.

Some may say, “Well, the product owner has to make sure that the requirements are exactly what the user needs!”

I would say, The end user doesn’t even know what they need until they see something concrete and they will then start forming an educated opinion about what they REALLY want. In other words, even if your product owner was a psychic, he still won’t get what the end-user will really pay for, simply because that this very end user doesn’t really know what to expect and what he wants. It would be a huge waste of time and money to invest in what we, the engineers, think about how the product should be in our perfectly engineered worlds. Instead of actually waiting to get a firm final answer from the end-user, (y’know the dude who’s going to use the product for ten years to come), not us, that dude!

It basically works this way. So often, we engineers get caught in a cycle of test, code, and refactoring when we don’t necessarily know that this is quite what the end user wants. Rather than test driven development, we should start from ensuring that what we are writing is exactly what the end user desires. This in effect turns the user into the test, except that this test will be the ultimate validation of our functions. Since the unit test (now the end user) is already “written” it is now the developers role to make this test pass. Once this test passes, the developers can refactor and add all the bells and whistles – thereby beautifying their code and making sure it is covered with unit tests (actual code this time).

This process allows a faster engagement between the end user and the developers. The faster feedback gives the developers a sense of what the user really needs and causes less disappointment for the developers when they have to remove all the code, testing, and refactoring into which they poured so much time and energy.

Let’s talk in numbers. If writing the unit test, coding, and refactoring costs $3000 (each stage at $1000), then that means that if the user changes his mind five times, the entire development cost will be $15,000, whereas if each time the end user changes his mind, we only do the development without the unit tests and refactoring, then the total cost is -$7000. This cuts the process by about 50% while achieving the very same end result, feature, and code.

Let’s put this in an equation:

(Testing + Developing + Refactoring) x 5 => User Acceptance = $15,000

(Developing) x 5 => User Acceptance + (Testing + Refactoring) = $7,000

The following drawing also illustrates the process:

I understand that some developers view Uncle Bob’s words as scripture, but let me remind you that at one time “waterfall methodology” was the only “right” way out there. You would be surprised at how many people defend waterfall methodology and enforce it today. Test Driven Development is a great methodology to protect our software, but what if we could take that methodology (Uncle Bob) to the market and teach him a couple of new tricks – to pay less and accomplish the very same thing, maybe even more?