bloomberg / pytest-pystack

Pytest plugin that runs PyStack on slow or hanging tests.
Apache License 2.0
12 stars 2 forks source link

pytest-pystack raises exception when using with pytester fixture #10

Open Czaki opened 5 months ago

Czaki commented 5 months ago

Describe the bug

Pytest provides pytester fixture to allow to validate if fixtures provided by a package works correctly: https://docs.pytest.org/en/7.1.x/reference/reference.html?highlight=pytester#pytester

However, this leads to run test in test and leads pytest-pystack to crash.

Process pystack_monitor:
Traceback (most recent call last):
  File "/home/czaki/.pyenv/versions/3.11.5/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/home/czaki/.pyenv/versions/3.11.5/lib/python3.11/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/home/czaki/.pyenv/versions/napari_3.11/lib/python3.11/site-packages/pytest_pystack/_monitor_process.py", line 57, in _run_monitor
    raise Exception(
Exception: new test should not start before previous test finished

This stacktrace comes from https://github.com/napari/napari/blob/cb7f46dfe0100c3afdd622faca768bc393b19636/napari/_tests/test_pytest_plugin.py

To Reproduce Steps to reproduce the behavior:

  1. Create a test that uses pytester fixture to run tests
  2. Run it in environment with pytest-pystack

Expected behavior

Allow use pytester with pytest-pystack

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

pablogsal commented 5 months ago

Will take a look at this soon

pablogsal commented 5 months ago

Hummm, I cannot reproduce this. I am checking with this test file:

import pytest
import time

pytest_plugins = 'pytester'

def test_make_napari_viewer(pytester):
    """Make sure that our make_napari_viewer plugin works."""

    # create a temporary pytest test file
    pytester.makepyfile(
        """
            import time
            time.sleep(100)
            assert 1 == 2

    """
    )
    # run all tests with pytest
    result = pytester.runpytest()

    # check that all 1 test passed
    result.assert_outcomes(passed=1)

And running python -m pytest the_file.py --pystack-threshold=2 -vv work correctly as expected (pystack prints output after 2 seconds):


...
    (Python) File "/venv/lib/python3.10/site-packages/pluggy/_result.py", line 61, in from_call
        result = func()
    (Python) File "/venv/lib/python3.10/site-packages/pluggy/_manager.py", line 470, in <lambda>
        lambda: oldcall(hook_name, hook_impls, caller_kwargs, firstresult)
    (Python) File "/venv/lib/python3.10/site-packages/pluggy/_callers.py", line 102, in _multicall
        res = hook_impl.function(*args)
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/runner.py", line 390, in pytest_make_collect_report
        call = CallInfo.from_call(collect, "collect")
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/runner.py", line 340, in from_call
        result: Optional[TResult] = func()
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/runner.py", line 388, in collect
        return list(collector.collect())
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/python.py", line 576, in collect
        self._register_setup_module_fixture()
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/python.py", line 589, in _register_setup_module_fixture
        self.obj, ("setUpModule", "setup_module")
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/python.py", line 315, in obj
        self._obj = obj = self._getobj()
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/python.py", line 573, in _getobj
        return importtestmodule(self.path, self.config)
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/python.py", line 520, in importtestmodule
        mod = import_path(
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/pathlib.py", line 584, in import_path
        importlib.import_module(module_name)
    (Python) File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
    (Python) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
    (Python) File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
    (Python) File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
    (Python) File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
    (Python) File "/venv/lib/python3.10/site-packages/_pytest/assertion/rewrite.py", line 178, in exec_module
        exec(co, module.__dict__)
    (Python) File "/tmp/pytest-of-root/pytest-26/test_make_napari_viewer0/test_make_napari_viewer.py", line 2, in <module>
        time.sleep(100)
``
Czaki commented 5 months ago

Your example does not contain a test in the created file. Try this one:

import pytest
import time

pytest_plugins = 'pytester'

def test_make_napari_viewer(pytester):
    """Make sure that our make_napari_viewer plugin works."""

    # create a temporary pytest test file
    pytester.makepyfile(
        """
            import time

            def test_sleep():
                time.sleep(1)
                assert 1 == 2

    """
    )
    # run all tests with pytest
    result = pytester.runpytest()

    # check that all 1 test passed
    result.assert_outcomes(passed=1)
Czaki commented 5 months ago

@pablogsal Any update?

pablogsal commented 5 months ago

I could reproduce with this example but with Python 3.13 beta 1 soon I cannot prioritise this currently as I need to attend other projects. Maybe @gusmonod can take a look

Otherwise if you want to give it a go we can take a PR :)

pablogsal commented 5 months ago

Oh, actually I haven't realised you opened a PR here:

https://github.com/bloomberg/pytest-pystack/pull/11

Can you add a test for this and we can merge it?

Czaki commented 5 months ago

Added test