You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was tossing up whether this should be a bug report or a feature request, as I wasn't able to work out whether the following is expected behaviour in the documention. It took a good day of solid troubleshooting to figure this one out, which I have found a workaround, so it's not a showstopper though it was difficult and very confusing to troubleshoot.
What's the problem?
pytest will, perhaps by design?, scan through and 'collect' (some, all?) third-party libraries used in x function, when x function iself is imported into a test to run.
This gives the impression that pytest:
collection has stalled when collecting tests in a large project,
flat out doesn't work properly when only one test exists,
is really frustrating to use with PyCharm (and other automated-test-runner tools) when it takes upwards of 20 seconds to collect tests before each test runs.
Current behaviour (as of pytest 8.3.2)
Note: I've used the awesome pytest-richtrace library (in --verbose mode) to help me figure this issue out, as there didn't appear to be a similar function in pytest to make pytests collection activities verbose.
arcgis is Esri's ArcGIS API for Python, allowing Python code to interact with Esri's Enterprise and Online geospatial systems without needing to write a mess of boilerplate REST API code. arcgis is a package I don't maintain, and don't need to test directly.
The same behaviour is present in both PyCharm and by manually invoking pytest with python -m via command line.
Example
# app.pyimportosfromarcgisimportGIS# Connection to an server Portal instancedefconnect():
portal=GIS(url=connection_url(domain, context), username=os.getenv('USERNAME'), username=os.getenv('PASSWORD'))
returnportaldefconnection_url(domain, context):
ifdomain=='arcgis.com'returnNone# API defaults to arcgis.com if None used as parameterelse:
return(f"https://{domain}/{context}")
# common.pydefcreate_wigwam():
# Do stuff here.returnTrue
# tests/test_common.py# another random test unrelated to app.py in the same directoryfromcommonimportcreate_wigwamdeftest_create_wigwam():
assertTrue
Note that:
connect() is not called,
there isn't a test for connect(),
connect() isn't imported into test_app.py,
the connection_url() function does not call connect(), and therefore call arcgis.GIS, and
test_app.py essentially does nothing other than import connection_url from app.py
I have also explicitly excluded venv and site-packages as directories in pytest.ini.
The code above, as it is written right now, will see pytest traverse the arcgis package within the virtual environment that runs this code. According to pytest-richtrace, pytest doesn't appear to collect anything in that package or the venv directory. pytest seems to ignore the os package.
Using pytest-richtrace I saw the following behaviour:
hook: pytest_collection
session: <Session exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=0>
...
hook: pytest_collectstart tests/test_app.py
INFO:numexpr.utils:Note: NumExpr detected 20 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8. # This is calling into the virtual environment.
INFO:numexpr.utils:NumExpr defaulting to 8 threads.
# Stall here after the above line is printed to console for a period of time, in my case at least 20 seconds, no other feedback is given.
hook: pytest_itemcollected tests/test_app.py::test_connection_url
hook: pytest_collection_modifyitems
hook: pytest_collection_finish
Simply commenting out the import line in test_app.py --
fromappimportconnection_url
-- prevents pytest traversing into arcgis to collect. All other tests complete pretty much instantaneously.
I haven't checked whether arcgis has any tests though the collection process certainly doesn't pick any up.
Describe the solution you'd like
Is this expected behaviour?
If expected behaviour:
Add a command line or configuration flag that tells pytest to exclude certain libraries from collection. (excluding directories doesn't do this)
Make the collection function more verbose with the --verbose flag, so that it's much easier to troubleshoot collection issues:
Print out the directory and file being examined for collection
Include timings when the --durations=0 flag is called
Workaround solution
Using MagicMock in unittest.mock allows pytest to traverse into app.py without also traversing into arcgis, stopping the stalling issue without having to comment out code or refactor unnecessarily:
# test_app.pyfromunittest.mockimportMagicMocksys.modules['arcgis'] =MagicMock()
# No other mocking code is needed, as this MagicMock completely substitutes arcgis when under test.
Many thanks!
The text was updated successfully, but these errors were encountered:
Lazy loading certainly appears to bypass the stall (with mocking code commented out in the test):
# app.pyimportos# from arcgis import GIS # Moved from here to connect()defconnect():
fromarcgisimportGIS# Lazily load GIS from arcgisportal=GIS(url=connection_url(domain, context), username=os.getenv('USERNAME'), username=os.getenv('PASSWORD'))
returnportaldefconnection_url(domain, context):
ifdomain=='arcgis.com'returnNone# API defaults to arcgis.com if None used as parameterelse:
return(f"https://{domain}/{context}")
pytest-richtrace doesn't show pytest traversing into arcgis.
Unfortunately this is not something Pytest can solve; it's just that importing a module executes all the top-level code and import arcgis is unreasonably slow.
Some kind of lazy imports might help in your situation but Pytest can't solve it for you.
Hi all!
I was tossing up whether this should be a bug report or a feature request, as I wasn't able to work out whether the following is expected behaviour in the documention. It took a good day of solid troubleshooting to figure this one out, which I have found a workaround, so it's not a showstopper though it was difficult and very confusing to troubleshoot.
What's the problem?
pytest
will, perhaps by design?, scan through and 'collect' (some, all?) third-party libraries used inx
function, whenx
function iself is imported into a test to run.This gives the impression that
pytest
:Current behaviour (as of
pytest 8.3.2
)Note: I've used the awesome
pytest-richtrace
library (in--verbose
mode) to help me figure this issue out, as there didn't appear to be a similar function inpytest
to makepytest
s collection activities verbose.The library I can reliably reproduce this issue with is
arcgis
. https://pypi.org/project/arcgis/arcgis
is Esri's ArcGIS API for Python, allowing Python code to interact with Esri's Enterprise and Online geospatial systems without needing to write a mess of boilerplate REST API code.arcgis
is a package I don't maintain, and don't need to test directly.The same behaviour is present in both PyCharm and by manually invoking
pytest
withpython -m
via command line.Example
Tests
Note that:
connect()
is not called,connect()
,connect()
isn't imported intotest_app.py
,connection_url()
function does not callconnect()
, and therefore callarcgis.GIS
, andtest_app.py
essentially does nothing other than import connection_url from app.pyI have also explicitly excluded
venv
andsite-packages
as directories in pytest.ini.The code above, as it is written right now, will see
pytest
traverse thearcgis
package within the virtual environment that runs this code. According topytest-richtrace
,pytest
doesn't appear to collect anything in that package or the venv directory.pytest
seems to ignore theos
package.Using
pytest-richtrace
I saw the following behaviour:Simply commenting out the import line in
test_app.py
---- prevents
pytest
traversing intoarcgis
to collect. All other tests complete pretty much instantaneously.I haven't checked whether
arcgis
has any tests though the collection process certainly doesn't pick any up.Describe the solution you'd like
pytest
to exclude certain libraries from collection. (excluding directories doesn't do this)--verbose
flag, so that it's much easier to troubleshoot collection issues:--durations=0
flag is calledWorkaround solution
Using
MagicMock
inunittest.mock
allowspytest
to traverse intoapp.py
without also traversing intoarcgis
, stopping the stalling issue without having to comment out code or refactor unnecessarily:Many thanks!
The text was updated successfully, but these errors were encountered: