[TIP] Testing a daemon with coverage (nose)
ned at nedbatchelder.com
Fri May 8 04:24:43 PDT 2009
Alfredo Deza wrote:
> I have just started to get into the habit of testing everything that I
> code, and a good friend of mine suggested the coverage plugin when
> using Nosetests.
> Right now I am working on a Daemon module for Python scripts. The
> module, when imported will make the current process detach from the
> terminal and run in the background as a daemon.
> When trying to test the module (importing it to test_module.py) I fail
> to correctly test any actions since it will convert test_module.py
> into a daemon.
> To circumvent this problem I created a "daemon script"
> (test_script.py) that would import the daemon module and effectively
> run in the background.
> The tests would check upon this daemon and the actions the module
> should be doing when working correctly (write to a file, kill a
> process etc).
> And this solution works fine for testing, but the "--with-coverage"
> flag does not cover the daemon module at all.
> When going further and specifying the package with
> "--cover-package=daemonModule" I get 0% coverage. I'm thinking this is
> expected since I am not importing the daemon module within
> test_module.py but rather on the daemon test script (test_script.py).
> And just to avoid some confusion, this is what I have:
> test_script.py => Script that will correctly daemonize so I can test
> test_module.py => Where all the tests go. Can't import the daemon
> module here or this will detach from the terminal.
> Do you guys know any other way that I could effectively test the
> daemon while still being able to maintain the Coverage plugin with a
> nice percentage value?
I'm not sure I've got all the details right, but it sounds like the
basic problem is that you have a test that nose can measure, but that
test spawns a new process, and the code in the new process is not
measured. Ironically, I have the same problem when coverage-testing
One possibility is to remove daemonization from the test run. This is
similar to the testing technique of using test doubles to remove
complicated dependencies from tests. If your code is organized so that
the main() of the daemon is callable directly, you can write a test that
invokes the main directly, rather than in a separate process, and
measure code coverage that way.
Another method would be to invoke coverage programmatically in the
daemon itself. This is less desirable because you have to modify your
product code to deal with testing issues, but would give you more
realistic measurement since the code really is running as a daemon.
Ned Batchelder, http://nedbatchelder.com
More information about the testing-in-python