-
Notifications
You must be signed in to change notification settings - Fork 214
Coverage fails for subprocess when communicate(timeout) is called, only when running python setup.py test
#276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
python setup.py test
python setup.py test
@ionelmc this is a specifically comprehensive version of the issue you asked me to move before. Please check it out if you have the time |
Some WorkaroundsTinkering around this issue, I was able to come up with the following workarounds. I don't know why they work as opposed to Workaround 1Running Workaround 2Since Workaround 1 worked, I observed that when I run pip install first BEFORE running
Workaround 3I also had a way to bypass The idea is to run coverage in parallel mode and run the subprocess with
Questions
|
Oooof ... so there are two issues here:
Can you avoid using |
Yeah, that's my workaround for now (running pytest directly). As an additional comment, I don't think signals are used in For the general solution, I'm betting that workaround 3 has promise, ie. setting Coverage docs says you can inject |
You can use I'm afraid there's no other way to put this: |
Coverage does not pick up sucessfull CLI tests pytest-dev/pytest-cov#276
I'm experiencing a similar problem (coverage metrics not collected from subprocess terminated by timeout) even when running It can be reproduced with this
And with this
pytest gives 0% coverage:
Without a timeout (e.g., with I understand that this is because the subprocess is not running the
As a workaround, I could send a signal to the process after the timeout and trigger the write of coverage data (I need
And this
I get 100% coverage after a timeout:
But this requires changes to the code under test (and |
Use sigterm or sigint - those are normally used to stop a running process. |
Thank you; But I was also looking for a way to avoid modifying the program under test; given that the subprocess is a Python process, one way could be registering the signal handler inside
(The It's unfortunate that |
I believe you could implement your own subprocess.run that handles timeouts better in your test suite. That would not add testing concerns in the delivered code, just make the test suite a little bit uglier - I think that's acceptable (and it looks like a matter of 1-2 extra lines of code - proc.communicate+exception handling). For the cleanup routine I would use |
Thanks! |
Originally posted by @Hikari9 in ionelmc/cookiecutter-pylibrary#13 (comment)
Summary
Coverage is not collected in
subprocess.Popen
when timeout is raised bycommunicate(timeout=...)
.This only occurs in tests that are run with
python setup.py test
(runningpytest
works fine).Versions
$> lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic
Problem Details
Use case: I want to test
if __name__ == '__main__':
sections in my program.Context: I run tests with
python setup.py test
. All my test requirements are in thetests_require
argument (not pip install). Essentially, mysetup.py
file looks like this:These are the contents of my config file (
setup.cfg
):I want to test the following program with
__name__ == '__main__'
, which MAY RUN INDEFINITELY.A similar real-world program like this would be some server listener (Flask, RabbitMQ, etc).
The following would be a simple example (a main program will run for 4 seconds):
I want to test with the CLI command "python -m <module>" (with coverage).
I don't want to transfer to a
def main()
function then call from the test, or useimp.load_module
. I just want to test the actual pure CLI method that runningpython -m sample.program
works without exceptions, without sacrificing coverage.How I tested this was to use
subprocess.Popen
that runspython -m sample.program
, like the following:The test will open a subprocess running
python -m <module>
, effectively going inside theif __name__ == '__main__'
block. Since the process times out 3 seconds (before 4 seconds), then the test should pass. And according to subprocess docs,Therefore, there should be no issue with
SIGTERM
or some other terminate signal, which according to Coverage.py docs, are issues in writing to coverage files, or so I've thought...Ideally, this should work with
python setup.py test
.Expected Result:
Have 100% code coverage
HOWEVER (the real world is harsh 😭 😭 😭 😭)
Actual Result:
The total coverage is effectively 0% even though tests PASSED (see additional log below)...
Additional Logs
Full log of
python setup.py test
:Notice that total coverage is 0% even though it should be 100%.
Also, this suspicious line says a lot I think?
How to reproduce bug
Create a project with the following directory structure:
See file contents from Problem Details section.
Create and activate virtual environment (Python 3.7.1)
Make sure packages are initially empty
Run tests
python setup.py test
Some workarounds
See comment #276 (comment) below.
Related Issues
The text was updated successfully, but these errors were encountered: