Could Python supplant Java?

Duncan Booth duncan at NOSPAMrcp.co.uk
Wed Aug 21 14:25:15 CEST 2002


joeking at merseymail.com (FISH) wrote in 
news:dbc5020.0208210349.3aca6686 at posting.google.com:

>> Programs *should* be tested before shipping
>> (ok, I know it's a dream but... )
> 
> Software testing is the *LAST* line of defense against bugs,
> not the *FIRST* !!!  ;-)

Oh dear. I can see there is a fundamental point of disagreement here.
My viewpoint is that software testing is the *FIRST* line of defense 
against bugs. It may also be the last line and several other lines in 
between: TDD doesn't remove the need for later stages of testing, it just 
reduces the cost of them.

> 
> A good programmer uses appropriate techniques and tools to
> try to minimise the number of bugs which get into software
> in the first place - before it even hits testing.
> 
Could you try to think of testing as something continuous with the other 
parts of development: design and coding? Repeating the development cycle: 
test, design, code, test, refactor, test on a microscopic scale.

> 
> [snip...]
>> >  Dynamic types are less
>> > hassle to work with, but of course they push an added burden of
>> > testing onto the developer
>> 
>> No. Write (good) tests first, then write your code, then let the 
>> computer run the tests.
> 
> 
> And how do I test the tests?  (If your test software is there to
> ensure your program works - what is ensuring your test software
> works?  Do you have test test software?  And test test test 
> software?)  We're back to what I said before - testing is the
> LAST line of defense against bugs.

You write a test. You run it. IT FAILS. This is important. If it passes, 
then there is something wrong with the test, or with your understanding of 
what the code already does. Now you write some code, the absolute minimum 
that allows the test to pass. Now you run the tests again.

You now know that the test works: it tests something that the code didn't 
do a few minutes ago, but now does. You wrote the test before you even 
thought about how to write the code. This means that you were able to write 
something to test the expected outcome, not the implementation. Then you 
went on to think about how to implement the absolute minimum for that test 
to pass. This may have involved simply returning the expected value, not 
actually implementing the code 'properly' because the important thing at 
this point is to verify the test.

At this point you have a working test, and 'working' but not very nice 
code. You now refactor the code. You rerun your tests as you do this to 
ensure you never break anything.

Eventually you get to code that satisfies you, so you can start again from 
the top with another test. 

Red bar (test fails), Green bar (test passes), Refactor
Every test fails at least once. That is how you test the tests.

If you do add another test, and it passes first time (it happens!) then you 
can change the code to make the test fail. The important point though is 
that the test must always fail at once, otherwise you won't know it works.

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



More information about the Python-list mailing list