Multiprocessing support

Although pytest-cov supports multiprocessing there are few pitfalls that need to be explained.

Abusing Process.terminate

It appears that many people are using the terminate method and then get unreliable coverage results.

On Linux usually that means a SIGTERM gets sent to the process. Unfortunately Python don’t have a default handler for SIGTERM so you need to install your own. Because pytest-cov doesn’t want to second-guess (not yet, add your thoughts on the issue tracker if you disagree) it doesn’t install a handler by default, but you can activate it by doing anything like:

from pytest_cov.embed import cleanup_on_sigterm
cleanup_on_sigterm()

# alternatively you can do this

from pytest_cov.embed import cleanup

def my_handler(signum, frame):
    cleanup()
    # custom cleanup
signal.signal(signal.SIGTERM, my_handler)

On Windows there’s no nice way to do cleanup (no signal handlers) so you’re left to your own devices.

Ungraceful Pool shutdown

Another problem is when using the Pool object. If you run some work on a pool in a test you’re not guaranteed to get all the coverage data unless you use the join method.

Eg:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

    p.join()  # <= THIS IS ESSENTIAL

Ungraceful Process shutdown

There’s an identical issue when using the Process objects. Don’t forget to use .join():

from multiprocessing import Process

def f(name):
    print('hello', name)

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()

    p.join()  # <= THIS IS ESSENTIAL