Monday, February 8, 2016

That thing called testing


There is always a lot of discussions about testing in general, what to test (class, method, behavior, use case , feature, UI) ? when to test (after, before, during) ? how to do it ? like this one between DHH Martin Fowler and Kent Beck, which got a lot of attention, so i decided to make a blog series to discuss the different aspects.of testing, that summarize my thoughts and my experience, i will cover their different types, why, how, when ? what are the common problems related to tests in general that got some people away from it, then i will present what worked for me, i will try to be objective and pragmatic, hopefully you will find it helpful. So let's start by:

Why we do testing:

Mainly there's two reasons for testing :


Safety from regressions



Safety from regressions is very important to support and maintain the software during it’s lifetime, they represent the reference and source of truth as software evolve and change over the years and the teams and persons that worked on it changed too.

By experience i have noticed two major problems
-Adding more of these tests to support new behaviours and requirements usually become more and more difficult as time goes by, which pushes developers to abandon testing and reduces the coverage.
- Also the existing tests will become brittle, slow and a burden to maintain which of course increases the cost of maintenance for the software, or the customer and management will push the developers to do a compromise on quality in order to ship faster, which in fact shorten the life of software (in the long run). Then the cost of maintenance will be higher and higher, this is the point where the product is called legacy code and nobody wants to touch it anymore until it's dead (usually a rewrite) and the cycle starts over again.

Have you been in similar scenario ? I have ! This scenario happens very often in IT industry. With very bad consequences to the business, the employees that get their lives miserable with impossible deadlines, overtime, bugs popping from everywhere, every change causes different problems.

I don't think the tests themselves are bad but the way to do them and their relation to the design.is what caused these issues.

Some people thought the solution is to to take in consideration the testing from the start, Test first or TDD also as Michael Feathers in his famous book Working with legacy code define a good software as testable software, which bring us to the second reason for testing.

Drive design


To TDD or not to TDD that's the question !
TDD i think is the most problematic one, basically many of the problems that were mentioned by DHH and others that it leads to over-engineering a lot of mocks since when you start with tests you have nothing so you fake it until you make it :) it leads to too decoupled systems that loose cohesion ! Also the end result depends on the ability of the developer to refactor ! So let's ask the question: 
do TDD really lead to a good design ? i will let the father of TDD answer that :

So TDD help to spot a bad design and keep you away from it, not necessarily leads to good design, also the problem i see with TDD is that the process is well documented in Kent Beck's book but get deformed and corrupted over time.
Also how to tell if a design is good ? Michael Feather says a good design (software) is easy to test.

This is why i believe that we have to make test easy and build infrastructure to support and help testing the system without being tied to implementation detail. Tests should be easy to write so developers dont hesitate to write a lot of them. They should be relevant when they broke, they should reflect a defect introduced by the new code. Remember : "Changing code and tests in the same time is not refactoring !"

There is different ways to testing and i firmly believe that we should adapt the way we do testing to what we test. For example testing a business process is different on how we do testing to algorithm or when we build API. 

More about this will be the topic for next coming posts, i will talk about what worked and what didn't and summarize the best approaches to do testing ! Stay tuned