[Tutor] IDEs
Steven D'Aprano
steve at pearwood.info
Wed Nov 24 14:06:00 CET 2010
Alan Gauld wrote:
> The basic idea in testing is to try to break your code. Try to think
> of every kind of evil input that could possibly come along and see
> if your code survives. In amongst all of that you should have a
> some valid values too, and know what to expect as out put.
Testing is more than just trying to break code of course. I'm reminded
of a quote:
"I find it amusing when novice programmers believe their main job is
preventing programs from crashing. ... More experienced programmers
realize that correct code is great, code that crashes could use
improvement, but incorrect code that doesn't crash is a horrible
nightmare." -- Chris Smith
Testing is an attempt to ensure that code is *correct* -- that it does
what it is supposed to do.
There are a number of different types of tests, with different purposes.
Unit tests are for testing that code behaves as expected. If you give
the function this input, this will be its result. (The result might be
to return a value, or it might be to raise an exception.) If you have a
function that's supposed to add two numbers, it's important to be sure
that it actually, ya know, *adds two numbers*, and not something else.
("It *almost* adds them, it's just that sometimes the answer is off by
one or two...")
Doctests are examples that you put into the documentation (usually into
docstrings of functions and methods). Their primary purpose is to be
examples for the reader to read, but the secondary aspect is that you
can run the examples and be sure that they actually work as they are
supposed to work.
Regression tests are to prevent bugs from re-occurring. For example,
suppose you have a function spam() and you discover it fails for one
particular input, "aardvark". The first thing you should do, before even
fixing the bug, is write a test:
assert spam("aardvark") == "expected result"
This test will fail, because there's a bug in spam(). Now go ahead and
fix the bug, and the test will then pass. If your code ever has a
*regression* that returns the bug in spam(), the test will fail again
and you will immediately notice. Regression tests are to prevent fixed
bugs from returning.
User Acceptance Tests are mostly relevant when you're building software
for a client. Both parties need a way to know when the software is
"done". Of course software is never done, but if you're charging $10000
for a software project, you need to have way of saying "This is where we
stop, if you want us to continue, it will cost you more". UATs give both
parties an objective way of telling that the promised functionality is
there (e.g. "if the user clicks the Stop button, processing must stop
within one second") and identifying bugs and/or areas that weren't
specified in enough detail.
Of course, all of these are fuzzy categories -- there's no hard line
between them.
> Test Driven Development tends to focus on the more normal inputs
> in my experience, but done properly your test code will usually
> be bigger than your production code. In a recent project that we
> completed we had 600k lines of production code and over a
> million lines of test code.
I can well believe that. I've had a look at a couple of my projects
(*much* smaller than 600 KLOC!) and I'm averaging about 800 lines in the
test suite per 1000 lines in the project. That's an over-estimate: the
1000 lines includes doc tests, so should be counted towards the tests.
Taking that into account, I get (very roughly) 1:1 ratio of test code to
production code.
> And we still wound up with over 50 reported bugs during Beta test...
> But that was much better than the 2000 bugs on an earlier project :-)
> But testing is hard.
Maybe so, but nothing beats running your test suite and seeing
everything pass!
--
Steven
More information about the Tutor
mailing list