Codentropy » archive for '4 - Definizione di Entropia del Codice'

Entropy and Tests

  • June 18th, 2006

Other Languages:

Italiano 

Today reasoning kickstart was given by a simple observation that anyone accustomed to Test Driven Development (TDD) has met, sooner or later.
Just for a moment, we won’t consider the otherwise mandatory refactoring patterns.
 

Day 1

We define the function A test;
The test passes (green bar).

 

Day 10

Our growing code is filled with A function calls. We notice that A needs a somewhat slight variation, for example a new input parameter opportunely referenced by its new code.

We modify A function consequently, together with all of its callers.

As gently asked before for the sake of this insane reckoning, that code modification is applied without following any strict refactoring pattern.

The reason why we ask no strict-refactoring divine intervention is that coding typing errors, or mnemonic oversights, may occur quite easily (even with manually applied refactoring).

Actually we are focused on estimating those errors induced from distraction, bounded by blood with the natural inaccuracy of a human being. Yes, programmers are human beings, trust me.

 

A Refactoring applied badly is worse than a refactoring not applied not at all.

 

The A function test passes again, another green bar (GB).
 

Day 20

We need another function, named B (yes, we are imaginative human beings, indeed), that internally references our previous A function.
We test B and A together, ending the day with a positive outcome (GB).

 

Day 180

During the development of our beautiful application, filled with hundreds of perfect classes and useful methods, it happens that we notice that B needs a new parameter (or a new if-statement, as you wish).

We eventually modify B and all the code that calls that function; afterall, we need to compile.

However, it’s the end of a sad day: sure we get a red bar (RB), but it’s the A test that doesn’t pass.

 

The Aftermath

Sounds Odd?

In a real production environment, this behavior is possible and quite recurring.

Even if A doesn’t call directly B (as we may infer by its static definition), the former can depend indirectly on the latter, through technologies related to other architectural domains, like a shared DBMS.

Omitting the meager complexity of the example, such behaviors may lead to some questions:

1. What changed the A test behavior?

2. If I had not used a test, could I have timely recognized the repercussions that a faulty B might have on A and its callers, in spite the apparently independence of A from B?

3. If I had applied the refactoring correctly, would I have to expect another green at the end of the day 180?

4. Without any tests, would I perceived “timely” or “too much late” the chaos injection made by a simple, stupid, pesky, natural oversight?

5. If the “chaotic” modification had been introduced by a careless colleague (or unaware of the context, because I had forgotten to document of the code, deuce!), would I have the same “luck” trying to discover the error/mistake without a (battery of) test(s)?

 

(Bad) Luck, (pesky) oversights, careless teammates (yes I know them…), tiredness, badly applied refactorings…are indeed lamer-only things, or cutting-edge senior developers too are doomed to sail in these muddy waters?

by Paolo Rainone

post navigation
about the author
View Paolo Rainone's LinkedIn profileView Paolo Rainone's profile
Paolo Rainone is a Certified Scrum Master. Click & go to the Scrum Alliance website.
search the diary

the rdc* theme