Skip to content
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

Fix ZeroDivisionError with 0 collected tests #2971

Merged
merged 2 commits into from
Nov 30, 2017

Conversation

blueyed
Copy link
Contributor

@blueyed blueyed commented Nov 28, 2017

This can easily happen with pytest-testmon.

Here's a quick checklist that should be present in PRs:

  • Add a new news fragment into the changelog folder
    • name it $issue_id.$type for example (588.bug)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of removal, feature, bugfix, vendor, doc or trivial
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."
  • Target: for bugfix, vendor, doc or trivial fixes, target master; for removals or features target features;
  • Make sure to include reasonable tests for your change if necessary

This can easily happen with pytest-testmon.
@nicoddemus
Copy link
Member

@blueyed thanks for the PR! 👍

Can you add a CHANGELOG entry and a test case to avoid a future regression? I tried adding one myself:

    def test_zero_tests_collected(self, testdir):
        output = testdir.runpytest()
        output.stdout.re_match_lines([
            r'=* 0 tests collected =*',
        ])

But this does not fail with a ZeroDivisionError...

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.009%) to 92.679% when pulling 0f5fb7e on blueyed:fix-ZeroDivisionError into 4d2f05e on pytest-dev:master.

@blueyed
Copy link
Contributor Author

blueyed commented Nov 29, 2017

Might take a while before coming back to it.

Here is the stacktrace for reference:

==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.6.3, pytest-3.3.0, py-1.5.2, pluggy-0.6.0
testmon=True, changed files: covimerage/logger.py,tests/test_logging.py, skipping collection of 56 items, run variant: default
rootdir: …/src/covimerage, inifile: setup.cfg
plugins: testmon-0.9.6, pdb-0.2.0, mock-1.6.3, cov-2.5.1, annotate-1.0.1
collected 59 items                                                                                                                                                                           

tests/test_cli.py FFFFFFFFFFFF
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/main.py", line 103, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/main.py", line 140, in _main
INTERNALERROR>     config.hook.pytest_collection(session=session)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR>     firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 201, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/main.py", line 150, in pytest_collection
INTERNALERROR>     return session.perform_collect()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/main.py", line 643, in perform_collect
INTERNALERROR>     config=self.config, items=items)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR>     firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 201, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/testmon/pytest_testmon.py", line 180, in pytest_collection_modifyitems
INTERNALERROR>     self.report_if_failed(item.nodeid)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/testmon/pytest_testmon.py", line 166, in report_if_failed
INTERNALERROR>     self.config.hook.pytest_runtest_logreport(report=test_report)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 617, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 222, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/__init__.py", line 216, in <lambda>
INTERNALERROR>     firstresult=hook.spec_opts.get('firstresult'),
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 201, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 76, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/pluggy/callers.py", line 180, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/terminal.py", line 272, in pytest_runtest_logreport
INTERNALERROR>     self.write_fspath_result(rep.nodeid, letter)
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/terminal.py", line 164, in write_fspath_result
INTERNALERROR>     self._write_progress_information_filling_space()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/terminal.py", line 322, in _write_progress_information_filling_space
INTERNALERROR>     msg = self._get_progress_information_message()
INTERNALERROR>   File "…/src/covimerage/.venv/lib/python3.6/site-packages/_pytest/terminal.py", line 316, in _get_progress_information_message
INTERNALERROR>     progress = self._progress_items_reported * 100 // self._session.testscollected
INTERNALERROR> ZeroDivisionError: integer division or modulo by zero

===================================================================================== 4 tests deselected =====================================================================================
========================================================================== 13 failed, 4 deselected in 0.06 seconds ===========================================================================

@nicoddemus
Copy link
Member

@blueyed thanks that helps.

I can see that testmon is triggering a self.config.hook.pytest_runtest_logreport(report=test_report) during pytest_collect_modifyitems, which explains why session.testscollected might be zero at that point.

@nicoddemus
Copy link
Member

Managed to write a test which reproduces the issue, thanks @blueyed!

@coveralls
Copy link

Coverage Status

Coverage increased (+0.002%) to 92.69% when pulling 6bbd741 on blueyed:fix-ZeroDivisionError into 4d2f05e on pytest-dev:master.

@blueyed
Copy link
Contributor Author

blueyed commented Nov 29, 2017

Awesome, thanks!

@nicoddemus nicoddemus merged commit 369c711 into pytest-dev:master Nov 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants