Unit Testing Techniques
elessar at nienna.org
Fri Jul 11 16:48:53 CEST 2008
I'm by no means a testing expert, but I'll take a crack at it.
Casey McGinty wrote:
> I'm familiar with the unittest module in Python, however I'm hoping
> someone can point me to some examples of more advanced usages of the
> framework. For example:
> 1. Using the framework to test a package with nested sub-packages and
> modules without having to hard code the location/name of each test module.
I've never run into this.
> 2. Testing class/methods that depend on file system directory
> structures, file data, or values read from system hardware.
Rule of thumb: always separate software from hardware. Write mock
classes or functions that do your hardware/file access that always
return known data (but remember to test for alpha and beta errors--make
sure both valid and invalid data are handled correctly). That way you
can test the client code that is accessing the hardware.
Testing the actual hardware/file access code can get more interesting.
If you're just reading files, your test suite should write the test
files in setUp, try to read them in the test* methods, then clean up in
tearDown. Again, remember to test both good and bad files.
In my shop, we do both hardware and software, and testing the comms
between them can be a real pain. We've done lots of interesting things
like wiring faults into the hardware with switches to connect and
disconnect them, recording command sequences, etc., but I expect this is
beyond the scope of what you're interested in. Just keep in mind that
testing a chunk of code requires at least as much creativity as writing
the code in the first place.
> 3. Testing class/methods that require simulating functionality from
> imported modules.
You can do neat things like this:
"""Returns known values."""
self._orig_function = mymodule.function
mymodule.function = my_mock_function
# remember to restore the original function
# unittest doesn't re-import modules
mymodule.function = self._orig_function
"""Test some code that uses mymodule."""
The dynamic nature of Python makes this sort of thing much easier than
> 4. Testing graphical interfaces and associated signal callback functions.
Again, there are lots of strategies you can use; the specifics depend on
you design and the toolkit.
1) You can mock the backend: make sure the right functions get called in
response the user actions.
2) Simulate user actions by manually posting events, calling functions, etc.
3) Mock the gui: make sure the backend is calling all the right GUI
Try to keep your backend and gui as independent as possible, it will
make testing much easier.
> Thank you.
I typically make a bunch of different suites that can be run
individually, in various combinations, or all together. Testing I/O
tends to be very slow, so it's nice to be able to turn of these tests
when you're working on other parts of the system.
There are many other testing tools besides unittest. The one I use the
most is coverage.py, to determine if my test suites are hitting all my
code. But you can check out pymock, doctest, nose, etc. too. You may
have to use a combination of tools to meet your needs.
There is also the Testing in Python mailing list
(http://lists.idyll.org/listinfo/testing-in-python). You can probably
get some advice there as well. The more specifics you can give, the better.
As you solve your testing problems, please take the time to post your
solutions (if you can) so we can all learn from your experiences.
More information about the Python-list