[Tutor] unit testing

Magnus Lyckå magnus@thinkware.se
Sat May 31 19:42:01 2003


Warning: I just got home from testing three fine malts (well,
two fine and one reasonable). Don't trust what I write below. :)

At 11:05 2003-05-31 -0700, Tom Plunket wrote:
>Sure- is there a way that I can call __import__ to look like
>"from x import *" though?

The simplest solution I can think of is to do

for filename in glob.glob('test_*.py):
     exec "from %s import *" % filename[:-3]

As I said, I advise against this.

>Interesting.  My only fear is that, for a program with a lot of
>modules, that this spits a lot of trash on the screen.

Real sample session:

P:\XXX>utsts.py
Running ccc_ut.py
.
----------------------------------------------------------------------
Ran 1 tests in 0.321s

OK
Running container_ut.py
............
----------------------------------------------------------------------
Ran 12 tests in 0.300s

OK
Running entities_ut.py
.............................................................................
----------------------------------------------------------------------
Ran 77 tests in 4.576s

OK
Running h2util_ut.py
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK
Running kbase_ut.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.641s

OK
Running matrix_ut.py
................
----------------------------------------------------------------------
Ran 16 tests in 0.010s

OK
Running session_ut.py
.....
----------------------------------------------------------------------
Ran 5 tests in 0.161s

OK
Running settings_ut.py
........
----------------------------------------------------------------------
Ran 8 tests in 0.260s

OK
Ran 8 test modules in 25.326 seconds real time

Make sure that you have a big screen buffer in your cmd.exe so
that you can scroll back if needed...

> > By doing it like this, I also know that each test module is run
> > independently, that there are no inadvertant dependencies between
> > test modules, since each module runs in a new process.
>
>That's a good point, although I do try to make sure there are no
>dependencies anyway by limiting my use of global variables to
>none and trying to always create new class instances.  :)

But this means that you might have problems with functions
defined in a test module. A quick check reveals that I have
a global function called 'init' in four of my test suites.

Running all the test suites in one big namespace means that
I have to avoid things like that. I prefer not to create
such restrictions for myself.

It's also quite possible to have the same class name in two
modules. Why not have an activities.Rest that handles relaxation
for the staff as well as a fractions.Rest that handles the
recycling fractions that don't go into categories like Glass,
metal etc. That will mean that if you first import class RestTest
from activities, and then RestTest from fractions, you will only
run the RestTest cases for fractions. activities.RestTest will
be hidden.

>C:\Documents and Settings\tom\My Documents>type test.py
>import test.regrtest

test.py is importing itself! :) Rename it to something else.

I guess the tutorial should have something about this in large
flaming letters where it discusses imports. Jen had almost the
same problem a few days ago. But it was funny that it was a self
reference this time! :)

>Hmm- there's something interesting.  Maybe I could hack unittest
>so that it takes a list of modules to run.  ...or maybe that's
>what that 'argv' parameter is for.  Hmm, maybe I can do it just
>by passing my 'tests' list in as argv.

Please tell us what you found. Separate namespaces are probably
enough protection, even if separate processes feel *very* safe...

As you see above, my total testing time is a lot longer than
the sum of times for each test. I'm sure module loading takes
some time, but maybe a better approach could save me ten seconds
or so...

>Yes indeed- I actually had similar frustrations when moving
>between C++ compilers, even.  The way to do things optimally
>often depended entirely on the compiler.  :(

You mean like when you build something with Visual C++ and get
no warnings, and in Unix you get hundreds, and realize that you
have done things that are obviously not correct C++, but the
"forgiving" Visual C++ compiler guessed what you meant, and didn't
even bother to tell you that you were wrong.

It's just the same as with HTML code for MS IE and other browsers.
Old MS tactics. Make it easy for programmers to get all their
code to run with our compiler, and make it difficult to get what
they develop with our tools to compile with other tools.


--
Magnus Lycka (It's really Lyckå), magnus@thinkware.se
Thinkware AB, Sweden, www.thinkware.se
I code Python ~ The shortest path from thought to working program