in reply to Re^2: Test Driven Development, for software and for pancakes
in thread Test Driven Development, for software and for pancakes

I am going to provide a real-world example of why tests are very important, based on a situation I ran into today.

I wanted to make some changes to my XS-based Bit::Manip distribution. One of my goals was to replace calls to stdint.h's pow() function with bit shift operations instead, to remove the reliance on the external library.

With my full test suite in place, I could freely replace things like:

#define MULT 2 return ((int)pow(MULT, bits) - 1) << lsb;

With:

return ((1 << bits) - 1) << lsb;

...and not have to worry about a thing, because all I had to do was make the change, run the tests, and on fail, go back to the math. Once all tests passed, I knew I was good.

Without a test suite, how would I ever know if I'm 100% accurate in my modification? I wouldn't be. Because all of my subs are covered entirely, I know that one change there didn't break anything within the sub its defined in, nor does the change break anything far away either.

Replies are listed 'Best First'.
Re^4: Test Driven Development, for software and for pancakes
by Anonymous Monk on Jul 25, 2017 at 18:21 UTC

    Hi there. Unwittingly, you have provided perhaps the perfect counter-example to TDD.

    Similar to how one cannot prove non-existence, one also cannot anticipate the unforeseeable. In other words, tests may guard against regressions, but they cannot save you from bugs.

    In C, bitwise shifts by less than operand width, are allowed. Given 32-bit unsigned int, a shift by 32 invokes undefined behavior. And in particular, on x86 this shift is equivalent to a NOP.

    print bit_mask(32, 0);

    But don't feel too bad about it; similar shift-mask bugs have occurred in security-critical contexts before...