Thursday, October 29, 2009

Unit tests - how not to do it

While at work I found myself in the situation of making some manually written unit-tests to work with a new version of software. Beside the fact that the tests were manually written they were written also without using any framework like cunit/cppunit/cpptest ... [I'm talking about c++ code] (yes it is stupid but wait ... there's more).

After I finished this task I saw that:

- some function changed its body but the functionality was the same
- the function's prototype was the same

This means that tests for that particular function need no modification in order to be run - which was correct.

The dilemma:

- tests for the previous version of function passed
- the same tests didn't pass this time although it was clearly that the function did *the same thing* (had the same functionality)

Why?

The test actually consisted in *also* couting the number of calls to several procedures invoked by the tested function (by stub-ing those invoked procedures and using some barbarian global variables).

You guessed it - the updated function made more/less calls to those stub-ed procedures, scrambling this way the number of calls expected.

Conclusions:

People confuse "unit testing" with "code coverage". Unit testing refers to the logic of the functions, *not* what procedures it calls or what parts of the code are run. That is another measure in testing called "code coverage".

The fact that usually the software helping you making tests also provides tools for showing the "code coverage" is not an excuse for this confusion; "code coverage" has nothing to do with "unit testing".

As a general rule: when you change/optimize a function's algorithm without affecting the functionality and the prototype is the same -> unit tests that previously worked *should* work with the new procedure.

Is it more important just to deliver something, instead of delivering something good? Where is the respect for the customer?

Monday, October 26, 2009

Evolution

For as long as I know I always wanted to make things work well. Even if it was a small plug that needed some new wires and isolation, or some stuff related to plumbing I always tried my best to make it as good as possible. And most of the time I succeeded. I always thought that this is a good way to evolve.

Now I'm an software engineer and my basic way of thinking is not too different from the one I had before, which I consider to be a good thing.

What happens when I'm somehow forced to choose a solution that does not satisfy me, that is recognized not to be a (very?) good choice, but it is the only one given the constraints (time being the no. 1 constraint most of the time)?

I know that compromises have to be made but given the fact that I develop software for safety critical equipments [public transportation to be more precise] I consider these kind of compromises trully life threatening. Since when time-to-market is more important than human life?

Is it that money rule everything and people just don't care enough about anything else?

I accept that I'm payed for doing that job and that's it, but there is some part of me telling that I can/should do more.

I may be exagerating or software engineering is not the choice that I should've made. Time will tell.