Troubleshooting¶
My tests won’t run!¶
You may encounter an issue where some of your test cases that use pytest-lsp
are unexpectedly skipped.
================================ test session starts =================================
platform linux -- Python 3.10.6, pytest-7.3.2, pluggy-1.1.0
rootdir: /home/username/projects/lsp/pytest-lsp
plugins: lsp-0.3.0, typeguard-3.0.2, asyncio-0.21.0
asyncio: mode=strict
collected 1 item
test_server.py s [100%]
================================== warnings summary ==================================
test_server.py::test_completions
/home/username/projects/lsp/pytest-lsp/venv/lib/python3.10/site-packages/_pytest/python.py:183: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.
You need to install a suitable plugin for your async framework, for example:
- anyio
- pytest-asyncio
- pytest-tornasync
- pytest-trio
- pytest-twisted
warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid)))
=========================== 1 skipped, 1 warning in 0.64s ============================
It’s likely that you forgot to add a @pytest.mark.asyncio
marker to your test function(s)
import pytest
@pytest.mark.asyncio
async def test_server(client: LanguageClient):
...
Alternatively, if you prefer, you can set the following configuration option in your project’s pyproject.toml
[tool.pytest.ini_options]
asyncio_mode = "auto"
In which case pytest-asyncio will automatically collect and run any async
test function in your test suite.
My tests hang!¶
If you find that your test suite hangs with no obvious cause or errors, make sure that all of your test functions are tagged with the appropriate scope
.
For exmaple, if you define your client fixture with scope="module"
@pytest_lsp.fixture(
scope="module",
config=ClientServerConfig(server_command=[sys.executable, "server.py"]),
)
async def client(lsp_client: LanguageClient):
Then all test cases that make use of the fixture must also be tagged with the same scope.
@pytest.mark.asyncio(scope="module")
async def test_completion_hello(client: LanguageClient):
DeprecationWarning
: Unclosed event loop¶
Depending on the version of pygls
(the LSP implementation used by pytest-lsp
) you have installed, you may encounter a DeprecationWarning
abount an unclosed event loop.
================================ test session starts =================================
platform linux -- Python 3.10.6, pytest-7.3.2, pluggy-1.1.0
rootdir: /home/username/projects/lsp/pytest-lsp
plugins: lsp-0.3.0, typeguard-3.0.2, asyncio-0.21.0
asyncio: mode=strict
collected 1 item
test_server.py . [100%]
================================== warnings summary ==================================
test_server.py::test_completions
/home/username/projects/lsp/pytest-lsp/venv/lib/python3.10/site-packages/pytest_asyncio/plugin.py:444: DeprecationWarning: pytest-asyncio detected an unclosed event loop when tearing down the event_loop
fixture: <_UnixSelectorEventLoop running=False closed=False debug=False>
pytest-asyncio will close the event loop for you, but future versions of the
library will no longer do so. In order to ensure compatibility with future
versions, please make sure that:
1. Any custom "event_loop" fixture properly closes the loop after yielding it
5. Your code does not modify the event loop in async fixtures or tests
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== 1 passed, 1 warning in 0.64s =============================
This is a known issue in pygls v1.0.2
and older, upgrading your pygls
version to 1.1.0
or newer should resolve the issue.
ScopeMismatch
Error¶
Important
This only applies to versions of pytest-asyncio
prior to v0.23.0
Setting your client fixture’s scope to something like session
will allow you to reuse the same client-server connection across multiple test cases.
However, you’re likely to encounter an error like the following:
__________________________ ERROR at setup of test_capabilities _________________________
ScopeMismatch: You tried to access the function scoped fixture event_loop with a session
scoped request object, involved factories:
/.../site-packages/pytest_lsp/plugin.py:201: def the_fixture(request)
This is due to the default event_loop
fixture provided by pytest-asyncio not living long enough to support your client.
To fix this you can override the event_loop
fixture, setting its scope to match that of your client.
@pytest.fixture(scope="session")
def event_loop():
"""Redefine `pytest-asyncio's default event_loop fixture to match the scope
of our client fixture."""
policy = asyncio.get_event_loop_policy()
loop = policy.new_event_loop()
yield loop
loop.close()