diff --git a/pyproject.toml b/pyproject.toml index e28738bb7da..f272c5bf013 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -160,6 +160,7 @@ testing = [ "pytest-pretty>=1.1.0", "pytest>=8.3.5", "pytest-rerunfailures>=15.1", + "pytest-xdist", "tensorstore>=0.1.32", "virtualenv>=20.17", "xarray>=0.16.2", @@ -250,6 +251,7 @@ testing = [ "pytest-pretty>=1.1.0", "pytest>=8.3.5", "pytest-rerunfailures>=15.1", + "pytest-xdist", "tensorstore>=0.1.32", "virtualenv>=20.17", "xarray>=0.16.2", diff --git a/src/napari/_qt/_tests/test_app.py b/src/napari/_qt/_tests/test_app.py index 90d5389b8c5..58c3a4313c9 100644 --- a/src/napari/_qt/_tests/test_app.py +++ b/src/napari/_qt/_tests/test_app.py @@ -38,6 +38,11 @@ def get_app_id(): def test_run_outside_ipython(make_napari_viewer, qapp, monkeypatch): """Test that we don't incorrectly give ipython the event loop.""" + # Mock the IPython module to avoid side effects from other tests + # when running with pytest-xdist + import sys + monkeypatch.setitem(sys.modules, 'IPython', None) + assert not _ipython_has_eventloop() v1 = make_napari_viewer() assert not _ipython_has_eventloop() diff --git a/src/napari/_tests/test_viewer.py b/src/napari/_tests/test_viewer.py index ba43b761526..46c801ba22a 100644 --- a/src/napari/_tests/test_viewer.py +++ b/src/napari/_tests/test_viewer.py @@ -28,7 +28,7 @@ def _get_provider_actions(type_): superclass ).values() ) - return actions + return sorted(actions, key=lambda action: action.__name__) def _assert_shortcuts_exist_for_each_action(type_): diff --git a/src/napari/conftest.py b/src/napari/conftest.py index 9cf69717f69..39462744fb2 100644 --- a/src/napari/conftest.py +++ b/src/napari/conftest.py @@ -247,7 +247,15 @@ def _auto_shutdown_dask_threadworkers(): We don't assert the number of threads in unchanged as other things modify the number of threads. """ - assert dask.threaded.default_pool is None + # Reset pool regardless of initial state (handles xdist case) + if dask.threaded.default_pool is not None: + if isinstance(dask.threaded.default_pool, ThreadPool): + dask.threaded.default_pool.close() + dask.threaded.default_pool.join() + else: + dask.threaded.default_pool.shutdown() + dask.threaded.default_pool = None + try: yield finally: diff --git a/tox.ini b/tox.ini index 188b7ea434c..ecf92d29065 100644 --- a/tox.ini +++ b/tox.ini @@ -107,9 +107,9 @@ indexserver = commands = cov: coverage run --parallel-mode \ !cov: python \ - -m pytest {env:PYTEST_PATH:} --color=yes --basetemp={envtmpdir} \ + -m pytest -n logical --dist loadfile --reruns 3 --reruns-delay 3 \ + {env:PYTEST_PATH:} --color=yes --basetemp={envtmpdir} \ --ignore tools --maxfail=5 --json-report \ - linux: --pystack-threshold=60 --pystack-args="--native-all" \ --json-report-file={toxinidir}/report-{envname}.json {posargs} \ --save-leaked-object-graph --import-mode=importlib