missing coverage in threads

Issue #582 closed
k3it
created an issue

I apologize for a cross post from http://stackoverflow.com/q/43991865/1653558 but it looks like this is a better place for the report

I'm getting some low coverage numbers on script with threads activated with a run() method. It seems that the coverage module is unable to keep track of all hits. Here is the code that demonstrates the problem. Running it should produce 100% coverage, but I'm getting 71.

from threading import Thread

class MyNestedThread(Thread):
        def run(self):
                print("hello from the nested thread!")

class MyThread(Thread):
        def run(self):
                print("Hello from thread")
                t = MyNestedThread()
                t.start()
                return

if __name__ == '__main__':
        for i in range(3):
                t = MyThread()
                t.start()
Hello from thread
hello from the nested thread!
Hello from thread
Hello from thread
hello from the nested thread!
hello from the nested thread!

Name     Stmts   Miss  Cover
----------------------------
foo.py      14      4    71%

re-running 'coverage run foo.py' sometimes gives a different %, and even 100% on occasion.

Comments (6)

  1. Ned Batchelder repo owner

    Thanks for writing this up. When I run your code with Python 3.6, and coverage.py 4.4.1, I get 100% every time. Can you give me some details of your environment? The output of "coverage debug sys" will have information. Also, can you run "coverage report -m" to show what lines are being missed?

    Thanks.

  2. k3it reporter
    version: 4.4
    python: 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 15:51:26) [MSC v.1900 32 bit (Intel)]
    platform: Windows-7-6.1.7601-SP1
    implementation: CPython
    
    Name     Stmts   Miss  Cover   Missing
    --------------------------------------
    foo.py      14      4    71%   5, 10-12
    

    I'm also getting missing coverage when deploying a python 3.5 project to Travis CI, which is linux based. so this does not look like a windows issue. I have not checked other releases of Python yet

  3. k3it reporter

    Hi Ned Here is the travis build that does not cover the run() method in recording_loop(QThread) class. This method definitely runs many times during travis tests https://travis-ci.org/k3it/qsorder/jobs/233002450 (note 51% coverage for qsorder.py, but it should be higher) source repo: https://github.com/k3it/qsorder/tree/qtgui

    coverage report https://coveralls.io/builds/11518328/source?filename=pyQsorder%2Fqsorder.py#L622

    you are right. it seems that in some environments the issue does not exist. but I don't see what triggers it.

  4. Will S

    I came across this ticket searching for information on using coverage.py with Qt's QThreads and PyQt (nothing else really came up). I think a QThread is totally different from a Python Thread because QThread is a Qt C++ class that PyQt is binding (but I haven't tried to understand how PyQt runs Python code from different QThreads). So I think the qsorder coverage issue is different from the example in the opening post.

    I am guessing there is no easy way for coverage.py to track code run in QThreads? Workarounds (for me) would be to refactor the application to have a single threaded testing mode or to use function-level tests for the functions that get run from QThreads.

  5. Log in to comment