GithubHelp home page GithubHelp logo

pytest-aiohttp's Introduction

pytest-aiohttp

pytest plugin for aiohttp support

The library provides useful fixtures for creation test aiohttp server and client.

Installation

$ pip install pytest-aiohttp

Add asyncio_mode = auto line to pytest configuration (see pytest-asyncio modes for details). The plugin works with strict mode also.

Usage

Write tests in pytest-asyncio style using provided fixtures for aiohttp test server and client creation. The plugin provides resources cleanup out-of-the-box.

The simple usage example:

from aiohttp import web


async def hello(request):
    return web.Response(body=b"Hello, world")


def create_app():
    app = web.Application()
    app.router.add_route("GET", "/", hello)
    return app


async def test_hello(aiohttp_client):
    client = await aiohttp_client(create_app())
    resp = await client.get("/")
    assert resp.status == 200
    text = await resp.text()
    assert "Hello, world" in text

See aiohttp documentation <https://docs.aiohttp.org/en/stable/testing.html#pytest> for more details about fixtures usage.

pytest-aiohttp's People

Contributors

aamalev avatar alefteris avatar asvetlov avatar c-bata avatar danigm avatar dreamsorcerer avatar f0t0n avatar jvstme avatar lgtm-com[bot] avatar matrixise avatar pashadia avatar pre-commit-ci[bot] avatar saikonen avatar scop avatar sirosen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pytest-aiohttp's Issues

Support for asynchronous `create_app()` function in the fixture

Long story short

For now, if function create_app is asynchronous, then it's not possible to use it for initialize aiohttp_client.

Code:

# app.py
async def create_app() -> web.Application:
    app = web.Application()
    await setup_app(app)
    return app
# conftest.py
@pytest.fixture(scope='function')
async def rest_client(aiohttp_client):
    from app import create_app
    client = await aiohttp_client(create_app)
    yield client
# test_app.py
@pytest.mark.asyncio
async def test_app(rest_client: TestClient):
    resp: Response = await rest_client.get('/')
    assert resp.status == 200

Traceback:

    def wrapper(*args, **kwargs):
        loop = kwargs['event_loop']
        request = kwargs['request']
        if strip_event_loop:
            del kwargs['event_loop']
        if strip_request:
            del kwargs['request']
    
        gen_obj = f(*args, **kwargs)
    
        async def setup():
            res = await gen_obj.__anext__()
            return res
    
        def finalizer():
            """Yield again, to finalize."""
            async def async_finalizer():
                try:
                    await gen_obj.__anext__()
                except StopAsyncIteration:
                    pass
                else:
                    msg = "Async generator fixture didn't stop."
                    msg += "Yield only once."
                    raise ValueError(msg)
    
            loop.run_until_complete(async_finalizer())
    
        request.addfinalizer(finalizer)
    
>       return loop.run_until_complete(setup())

/usr/local/lib/python3.7/site-packages/pytest_asyncio/plugin.py:97: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.7/asyncio/base_events.py:584: in run_until_complete
    return future.result()
/usr/local/lib/python3.7/site-packages/pytest_asyncio/plugin.py:78: in setup
    res = await gen_obj.__anext__()
conftest.py:336: in rest_client
    client = await aiohttp_client(create_app)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

__param = <coroutine object create_app at 0x7efce6af07c8>, server_kwargs = None, args = (), kwargs = {}

    async def go(__param, *args, server_kwargs=None, **kwargs):  # type: ignore
    
        if (isinstance(__param, Callable) and  # type: ignore
                not isinstance(__param, (Application, BaseTestServer))):
            __param = __param(loop, *args, **kwargs)
            kwargs = {}
        else:
            assert not args, "args should be empty"
    
        if isinstance(__param, Application):
            server_kwargs = server_kwargs or {}
            server = TestServer(__param, loop=loop, **server_kwargs)
            client = TestClient(server, loop=loop, **kwargs)
        elif isinstance(__param, BaseTestServer):
            client = TestClient(__param, loop=loop, **kwargs)
        else:
>           raise ValueError("Unknown argument type: %r" % type(__param))
E           ValueError: Unknown argument type: <class 'coroutine'>

/usr/local/lib/python3.7/site-packages/aiohttp/pytest_plugin.py:318: ValueError

Expected behaviour

If create_app declared as asynchronous function, then aiohttp_client fixture is initialized with this function as usual.

Actual behaviour

ValueError: Unknown argument type: <class 'coroutine'> raises.

Environment

python --version ; pip freeze | grep aiohttp
Python 3.7.3
aiohttp==3.5.4
aiohttp-devtools==0.12
aiohttp-jwt==0.4.0
pytest-aiohttp==0.3.0

PytestDeprecationWarning with pytest 7.2.0

This line

@pytest.mark.tryfirst

causes

pytest.PytestDeprecationWarning: The hookimpl pytest_configure uses old-style configuration options (marks or attributes).
Please use the pytest.hookimpl(tryfirst=True) decorator instead
 to configure the hooks.
 See https://docs.pytest.org/en/latest/deprecations.html#configuring-hook-specs-impls-using-markers

with pytest 7.2.0.

README should talk about avoiding _explicit_ loading pytest module

Hi,

Currently, README.rst describes that this module alows use of pytest module "without implicitly loading it".

Seems to me you are using meant to say explicitly in that sentence (i.e. that it loads pytest module automatically without needing to state it explicitly).

chardet can't be replaced by cchardet

Hi,

I removed chardet library and used cchardet to replace it.
Then I run unit test and got the error
TypeError: test_hello() missing 2 required positional arguments: 'test_client' and 'loop'

The test code is from website documentation.

# -*- coding: utf-8 -*-
from aiohttp import web

async def hello(request):
    return web.Response(text='Hello, world')

async def test_hello(test_client, loop):
    app = web.Application(loop=loop)
    app.router.add_get('/', hello)
    client = await test_client(app)
    resp = await client.get('/')
    assert resp.status == 200
    text = await resp.text()
    assert 'Hello, world' in text

I'm not sure it's cchardet problem or not. ๐Ÿ˜ž

Thank you.

Compatibility with Python3.8 + Windows

I'm getting this error using the aiohttp_server fixture

self = <ProactorEventLoop running=False closed=True debug=False>
sock = <socket.socket fd=1496, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 50202)>

    def _stop_serving(self, sock):
        future = self._accept_futures.pop(sock.fileno(), None)
        if future:
            future.cancel()
>       self._proactor._stop_serving(sock)
E       AttributeError: 'NoneType' object has no attribute '_stop_serving'

The complete error log in https://dev.azure.com/johander-182/aiosonic/_build/results?buildId=281&view=logs&jobId=725faacd-bdc4-550c-e77e-408d4e6e9756&j=725faacd-bdc4-550c-e77e-408d4e6e9756&t=e856c400-4037-5c54-1baa-9af2a6ffb100

It works ok with windows and mac

pytest-aiohttp is incompatible with pytest-asyncio v0.14.0

When running pytest-aiohttp with pytest-asyncio v0.14.0 I am seeing the following error:

RuntimeError: Timeout context manager should be used inside a task

This is related to a change in pytest-asyncio concerning event loop handling (see pytest-dev/pytest-asyncio#170). Explanation in pytest-dev/pytest-asyncio#170 (comment)

Would it be possible to coordinate with the pytest-asyncio team so both your awesome libraries can be used at the same time.

how to set the port to which web server listen

https://github.com/aio-libs/pytest-aiohttp

I did a little bit modified as follows:

import pytest
import json
import asyncio
import aiohttp
import requests
from aiohttp import web

routes = web.RouteTableDef()
print("\nroutes = {}".format(routes))


@routes.get('/notify/hello/{id}')
async def hello(request):
    print("post notify = {}".format(request))
    return web.Response(body=b'Hello, world')

def create_app(loop):
    app = web.Application(loop=loop)
    app.router.add_route('GET', '/', hello)
    return app

async def test_hello(test_client):
    client = await test_client(create_app)
    while True:
        pass
        # print("server running")

    resp = await client.get('/')
    assert resp.status == 200
    text = await resp.text()
    assert 'Hello, world' in text

I want to ensure server running continuously.

Created client hello to test server as follows:

import pytest
import json
import asyncio
import aiohttp
import requests
from aiohttp import web


SERVER_IP = "127.0.0.1"
SERVER_PORT= "80"

DEFAULT_HTTP_PATH='http://'+SERVER_IP+':'+SERVER_PORT

msg_path = {
    6: '/notify/hello/1111',

}

GET = "get"
def test_get_hello_1111():
    path = DEFAULT_HTTP_PATH + msg_path[6]

    async def method():
        resp = await aiohttp.ClientSession().request(
            GET, path)

        print('Response Info -----')
        print(str(resp))
        print('Response Body -----')
        print(await resp.text())
        assert 200 == resp.status
    asyncio.get_event_loop().run_until_complete(method())
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 127.0.0.1:80 ssl:False [Connect call failed ('127.0.0.1', 80)]

I tried port number 8080, same failure Connect call failed ('127.0.0.1', 8080).

How to set the port in the sample program?
How to find the port web server is listening to?

1.0.4: pytest is failing

Looks like some updates are needed for latest pytest 7.2.0

+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.15, pytest-7.2.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/pytest-aiohttp-1.0.4, configfile: setup.cfg, testpaths: tests
plugins: aiohttp-1.0.4, asyncio-0.20.2
asyncio: mode=auto
collected 10 items

tests/test_fixtures.py FFFF                                                                                                                                          [ 40%]
tests/test_obsolete_fixtures.py ...                                                                                                                                  [ 70%]
tests/test_switch_mode.py ...                                                                                                                                        [100%]

================================================================================= FAILURES =================================================================================
___________________________________________________________________________ test_aiohttp_plugin ____________________________________________________________________________
/home/tkloczko/rpmbuild/BUILD/pytest-aiohttp-1.0.4/tests/test_fixtures.py:107: in test_aiohttp_plugin
    result.assert_outcomes(passed=8)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:567: in parseoutcomes
    return self.parse_summary_nouns(self.outlines)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:585: in parse_summary_nouns
    raise ValueError("Pytest terminal summary report not found")
E   ValueError: Pytest terminal summary report not found
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1170, in runpytest_inprocess
    reprec = self.inline_run(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1135, in inline_run
    ret = main([str(x) for x in args], plugins=plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/lib/python3.8/site-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1229, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 288, in load_setuptools_entrypoints
    self.register(plugin, name=ep.name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 489, in register
    ret: Optional[str] = super().register(plugin, name)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 103, in register
    hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 460, in parse_hookimpl_opts
    return _get_legacy_hook_marks(
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 374, in _get_legacy_hook_marks
    warn_explicit_for(cast(FunctionType, method), message)
  File "/usr/lib/python3.8/site-packages/_pytest/warning_types.py", line 171, in warn_explicit_for
    raise type(w)(f"{w}\n at {filename}:{lineno}") from None
pytest.PytestDeprecationWarning: The hookimpl pytest_configure uses old-style configuration options (marks or attributes).
Please use the pytest.hookimpl(tryfirst=True) decorator instead
 to configure the hooks.
 See https://docs.pytest.org/en/latest/deprecations.html#configuring-hook-specs-impls-using-markers
 at /home/tkloczko/rpmbuild/BUILDROOT/python-pytest-aiohttp-1.0.4-5.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:21
_________________________________________________________________________ test_aiohttp_raw_server __________________________________________________________________________
/home/tkloczko/rpmbuild/BUILD/pytest-aiohttp-1.0.4/tests/test_fixtures.py:142: in test_aiohttp_raw_server
    result.assert_outcomes(passed=1)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:567: in parseoutcomes
    return self.parse_summary_nouns(self.outlines)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:585: in parse_summary_nouns
    raise ValueError("Pytest terminal summary report not found")
E   ValueError: Pytest terminal summary report not found
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1170, in runpytest_inprocess
    reprec = self.inline_run(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1135, in inline_run
    ret = main([str(x) for x in args], plugins=plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/lib/python3.8/site-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1229, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 288, in load_setuptools_entrypoints
    self.register(plugin, name=ep.name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 489, in register
    ret: Optional[str] = super().register(plugin, name)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 103, in register
    hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 460, in parse_hookimpl_opts
    return _get_legacy_hook_marks(
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 374, in _get_legacy_hook_marks
    warn_explicit_for(cast(FunctionType, method), message)
  File "/usr/lib/python3.8/site-packages/_pytest/warning_types.py", line 171, in warn_explicit_for
    raise type(w)(f"{w}\n at {filename}:{lineno}") from None
pytest.PytestDeprecationWarning: The hookimpl pytest_configure uses old-style configuration options (marks or attributes).
Please use the pytest.hookimpl(tryfirst=True) decorator instead
 to configure the hooks.
 See https://docs.pytest.org/en/latest/deprecations.html#configuring-hook-specs-impls-using-markers
 at /home/tkloczko/rpmbuild/BUILDROOT/python-pytest-aiohttp-1.0.4-5.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:21
____________________________________________________________ test_aiohttp_client_cls_fixture_custom_client_used ____________________________________________________________
/home/tkloczko/rpmbuild/BUILD/pytest-aiohttp-1.0.4/tests/test_fixtures.py:169: in test_aiohttp_client_cls_fixture_custom_client_used
    result.assert_outcomes(passed=1)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:567: in parseoutcomes
    return self.parse_summary_nouns(self.outlines)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:585: in parse_summary_nouns
    raise ValueError("Pytest terminal summary report not found")
E   ValueError: Pytest terminal summary report not found
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1170, in runpytest_inprocess
    reprec = self.inline_run(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1135, in inline_run
    ret = main([str(x) for x in args], plugins=plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/lib/python3.8/site-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1229, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 288, in load_setuptools_entrypoints
    self.register(plugin, name=ep.name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 489, in register
    ret: Optional[str] = super().register(plugin, name)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 103, in register
    hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 460, in parse_hookimpl_opts
    return _get_legacy_hook_marks(
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 374, in _get_legacy_hook_marks
    warn_explicit_for(cast(FunctionType, method), message)
  File "/usr/lib/python3.8/site-packages/_pytest/warning_types.py", line 171, in warn_explicit_for
    raise type(w)(f"{w}\n at {filename}:{lineno}") from None
pytest.PytestDeprecationWarning: The hookimpl pytest_configure uses old-style configuration options (marks or attributes).
Please use the pytest.hookimpl(tryfirst=True) decorator instead
 to configure the hooks.
 See https://docs.pytest.org/en/latest/deprecations.html#configuring-hook-specs-impls-using-markers
 at /home/tkloczko/rpmbuild/BUILDROOT/python-pytest-aiohttp-1.0.4-5.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:21
_________________________________________________________________ test_aiohttp_client_cls_fixture_factory __________________________________________________________________
/home/tkloczko/rpmbuild/BUILD/pytest-aiohttp-1.0.4/tests/test_fixtures.py:220: in test_aiohttp_client_cls_fixture_factory
    result.assert_outcomes(passed=2)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:567: in parseoutcomes
    return self.parse_summary_nouns(self.outlines)
/usr/lib/python3.8/site-packages/_pytest/pytester.py:585: in parse_summary_nouns
    raise ValueError("Pytest terminal summary report not found")
E   ValueError: Pytest terminal summary report not found
--------------------------------------------------------------------------- Captured stderr call ---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1170, in runpytest_inprocess
    reprec = self.inline_run(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/_pytest/pytester.py", line 1135, in inline_run
    ret = main([str(x) for x in args], plugins=plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/lib/python3.8/site-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1229, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 288, in load_setuptools_entrypoints
    self.register(plugin, name=ep.name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 489, in register
    ret: Optional[str] = super().register(plugin, name)
  File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 103, in register
    hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 460, in parse_hookimpl_opts
    return _get_legacy_hook_marks(
  File "/usr/lib/python3.8/site-packages/_pytest/config/__init__.py", line 374, in _get_legacy_hook_marks
    warn_explicit_for(cast(FunctionType, method), message)
  File "/usr/lib/python3.8/site-packages/_pytest/warning_types.py", line 171, in warn_explicit_for
    raise type(w)(f"{w}\n at {filename}:{lineno}") from None
pytest.PytestDeprecationWarning: The hookimpl pytest_configure uses old-style configuration options (marks or attributes).
Please use the pytest.hookimpl(tryfirst=True) decorator instead
 to configure the hooks.
 See https://docs.pytest.org/en/latest/deprecations.html#configuring-hook-specs-impls-using-markers
 at /home/tkloczko/rpmbuild/BUILDROOT/python-pytest-aiohttp-1.0.4-5.fc35.x86_64/usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:21
========================================================================= short test summary info ==========================================================================
FAILED tests/test_fixtures.py::test_aiohttp_plugin - ValueError: Pytest terminal summary report not found
FAILED tests/test_fixtures.py::test_aiohttp_raw_server - ValueError: Pytest terminal summary report not found
FAILED tests/test_fixtures.py::test_aiohttp_client_cls_fixture_custom_client_used - ValueError: Pytest terminal summary report not found
FAILED tests/test_fixtures.py::test_aiohttp_client_cls_fixture_factory - ValueError: Pytest terminal summary report not found
======================================================================= 4 failed, 6 passed in 3.02s ========================================================================
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-8fb365bf-55c2-45dd-bf96-208f54d343b4
<class 'OSError'>: [Errno 39] Directory not empty: '/tmp/pytest-of-tkloczko/garbage-8fb365bf-55c2-45dd-bf96-208f54d343b4'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616/test_rmtree_errorhandler_rerai0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_rmtree_errorhandler_rerai0'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616/test_rmtree_errorhandler_reado0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_rmtree_errorhandler_reado0'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616/test_safe_delete_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_delete_no_perms0'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616/test_safe_set_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_set_no_perms0'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616/test_safe_get_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_get_no_perms0'
  warnings.warn(
/usr/lib/python3.8/site-packages/_pytest/pathlib.py:79: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616
<class 'OSError'>: [Errno 39] Directory not empty: '/tmp/pytest-of-tkloczko/garbage-439f487e-9bb6-422e-8b73-84b1c517a616'
  warnings.warn(

Conflicts with pytest-asyncio (sample with redis)

Having following test file, things behave differently with different pytest plugins installed:

import aioredis
import pytest
from aiohttp import web


def init():
    """Create web.Application instance
    """
    app = web.Application()
    app.router.add_get('/', hello)
    app["redis_url"] = "redis://localhost:6379"
    app.on_startup.append(create_redis_pool)
    app.on_shutdown.insert(0, close_redis_pool)
    return app


async def hello(request):
    """url Handler for hello"""
    return web.Response(text='Hello, world')


async def create_redis_pool(app):
    """Create Redis connection pool"""
    redis_url = app["redis_url"]
    pool = await aioredis.create_redis_pool(redis_url, loop=app.loop)
    app["redis_pool"] = pool


async def close_redis_pool(app):
    """Close Redis connection pool"""
    pool = app["redis_pool"]
    pool.close()
    await pool.wait_closed()


# @pytest.fixture
# def loop(event_loop):
#     """Ensure usable event loop for everyone.
#
#     If you comment this fixture out, default pytest-aiohttp one is used
#     and things start failing (when redis pool is in place).
#     """
#     return event_loop


@pytest.fixture
def app(loop):
    """Application instance.
    """
    return init()


@pytest.fixture
async def cli(test_client, app, loop):
    """HTTP client for our application.
    """
    return await test_client(app)


async def test_hello(cli, loop):
    resp = await cli.get("/")
    assert resp.status == 200
    text = await resp.text()
    assert "Hello, world" in text

only pytest-aiohttp installed: all is fine

When only pytest-aiohttp is installed, the test runs well as it is.

============================================================================================= test session starts =============================================================================================
platform linux -- Python 3.6.3, pytest-3.4.0, py-1.5.2, pluggy-0.6.0
rootdir: /home/javl/devel/tis/dpo-tis-pns, inifile:
collected 1 item

tests/http/test_redisloop.py .                                                                                                                                                                          [100%]

========================================================================================== 1 passed in 0.06 seconds ===========================================================================================

[Process exited 0]

with pytest-asyncio, it fails

When also pytest-asyncio is installed, the test fails with:

self = <ConnectionsPool [db:0, size:[1:10], free:0]>

    async def wait_closed(self):
        """Wait until pool gets closed."""
        await self._close_state.wait()
        assert self._close_waiter is not None
>       await asyncio.shield(self._close_waiter, loop=self._loop)
E       RuntimeError: Task <Task pending coro=<pytest_fixture_setup.<locals>.wrapper.<locals>.setup() running at /home/javl/devel/tis/dpo-tis-pns/.tox/py36/lib/python3.6/site-packages/pytest_asyncio/plugin.p
y:117> cb=[_run_until_complete_cb() at /home/javl/.pyenv/versions/3.6.3/lib/python3.6/asyncio/base_events.py:176]> got Future <Future pending> attached to a different loop

.tox/py36/lib/python3.6/site-packages/aioredis/pool.py:177: RuntimeError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[33] > /home/javl/devel/tis/dpo-tis-pns/.tox/py36/lib/python3.6/site-packages/aioredis/pool.py(177)wait_closed()
-> await asyncio.shield(self._close_waiter, loop=self._loop)
   6 frames hidden (try 'help hidden_frames')
(Pdb++)

fix by masking loop fixture

To fix this problem (still using pytest-asyncio plugin), one has to uncomment the loop fixture.

Improve README

Since pytest-aiohttp now is the host of provided fixtures, their documentation should be moved out from aiohttp itself and placed into README.rst. The aiohttp doc can contain a simple usage example and a link to README for future reading.

Initial Update

Hi ๐Ÿ‘Š

This is my first visit to this fine repo, but it seems you have been working hard to keep all dependencies updated so far.

Once you have closed this issue, I'll create seperate pull requests for every update as soon as I find one.

That's it for now!

Happy merging! ๐Ÿค–

Scoping issues with pytest v3.5.0

When upgrading pytest from v3.4.2 to v3.5.0 the following error started appearing in all live aiohttp tests:

_______________________________________________________________________ ERROR at setup of TestAuthPost.test_sucess[pyloop] _______________________________________________________________________
ScopeMismatch: You tried to access the 'function' scoped fixture 'loop' with a 'class' scoped request object, involved factories
tests/end_to_end_tests/conftest.py:38:  def guest_instance(request, data_owner_instance)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:59:  def wrapper(*args, **kwargs)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:199:  def loop(loop_factory, fast, loop_debug)

Source Code

conftest.py

import pytest

from example.app import create_app


@pytest.fixture()
async def client(test_client):
    app = create_app()
    return await test_client(app)

test_auth_api.py

from datetime import datetime

import pytest
from aiohttp.helpers import BasicAuth

from example.common.auth import validate_jwt
from tests.common import AUTH_API_URL


@pytest.mark.usefixtures("client", "service_user_instance")
class TestPostAuth:
    async def test_success(self, client, service_user_instance):
        auth = BasicAuth(service_user_instance.username, service_user_instance.api_key, "utf-8")
        response = await client.post(AUTH_API_URL, auth=auth)

        assert response.status == 201

        response_json = await response.json()

        assert response_json.get("access_token") is not None
        assert response_json.get("expires_at") is not None

Running Tests with Pytest v3.4.2

=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.6.3, pytest-3.4.2, py-1.5.3, pluggy-0.6.0
rootdir: /path/to/Workspace/example, inifile: pytest.ini
plugins: aiohttp-0.3.0, hypothesis-3.52.0
collected 4 items                                                                                                                                                                                          

tests/end_to_end_tests/test_controllers/test_auth_api/test_auth_api_controller.py ....                                                                                                               [100%]

========================================================================================= 4 passed in 1.96 seconds =========================================================================================

Running Tests with Pytest 3.5.0

=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.6.3, pytest-3.5.0, py-1.5.3, pluggy-0.6.0
rootdir: /path/to/Workspace/example, inifile: pytest.ini
plugins: aiohttp-0.3.0, hypothesis-3.52.0
collected 4 items                                                                                                                                                                                          

tests/end_to_end_tests/test_controllers/test_auth_api/test_auth_api_controller.py EEEE                                                                                                               [100%]

================================================================================================== ERRORS ==================================================================================================
___________________________________________________________________________ ERROR at setup of TestPostAuth.test_success[pyloop] ____________________________________________________________________________
ScopeMismatch: You tried to access the 'function' scoped fixture 'loop' with a 'class' scoped request object, involved factories
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:59:  def wrapper(*args, **kwargs)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:199:  def loop(loop_factory, fast, loop_debug)
________________________________________________________________________ ERROR at setup of TestPostAuth.test_wrong_api_key[pyloop] _________________________________________________________________________
ScopeMismatch: You tried to access the 'function' scoped fixture 'loop' with a 'class' scoped request object, involved factories
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:59:  def wrapper(*args, **kwargs)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:199:  def loop(loop_factory, fast, loop_debug)
____________________________________________________________________ ERROR at setup of TestPostAuth.test_non_existing_username[pyloop] _____________________________________________________________________
ScopeMismatch: You tried to access the 'function' scoped fixture 'loop' with a 'class' scoped request object, involved factories
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:59:  def wrapper(*args, **kwargs)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:199:  def loop(loop_factory, fast, loop_debug)
_____________________________________________________________________ ERROR at setup of TestPostAuth.test_wrong_authorization[pyloop] ______________________________________________________________________
ScopeMismatch: You tried to access the 'function' scoped fixture 'loop' with a 'class' scoped request object, involved factories
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:59:  def wrapper(*args, **kwargs)
.testing-venv/lib/python3.6/site-packages/aiohttp/pytest_plugin.py:199:  def loop(loop_factory, fast, loop_debug)
========================================================================================= 4 error in 0.02 seconds ==========================================================================================

This issue is related to aiohttp#2880.

pytest-aiohttp freezes when using `asyncio.create_subprocess_exec` in a process that reads from stdin

Problem description

When running a test suite with pytest-aiohttp and aiohttp>3.0 the test suite hangs when calling Process.communicate passing an input parameter in a process spawned by asyncio.create_subprocess_exec (that has a pipe in stdin) the second time a test is ran (the issue does not present if only one test is ran - disregarding the order or which set of tests are selected).

How to reproduce

Installed packages:

aiohttp==3.4.4
async-timeout==3.0.1
atomicwrites==1.2.1
attrs==18.2.0
chardet==3.0.4
idna==2.7
more-itertools==4.3.0
multidict==4.4.2
pluggy==0.8.0
py==1.7.0
pytest==3.9.2
pytest-aiohttp==0.3.0
six==1.11.0
yarl==1.2.6

Create a file called test.py with this code

import asyncio

async def test_1():
    process = await asyncio.create_subprocess_exec(
            "cat",
            stderr=asyncio.subprocess.PIPE,
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE
            )
    stdout, stderr = await process.communicate(input="asyncio rules".encode())

    assert stdout == b"asyncio rules"

async def test_2():
    process = await asyncio.create_subprocess_exec(
            "cat",
            stderr=asyncio.subprocess.PIPE,
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE
            )
    stdout, stderr = await process.communicate(input="asyncio rules".encode())

    assert stdout == b"asyncio rules"

and then run python -m pytest test.py. The interpreter hangs when running the second test.

Reproducer systems

I was able to reproduce this issue in MacOs and Linux:

uname -a
Darwin C02VL073HTDG 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64
uname -a
Linux RedHat 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:55:56 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

asyncio_mode deprecation warning is emitted for test suites that don't use aiohttp at all

When pytest-aiohttp plugin is installed, practically every single test suite on my system emits the following deprecation warning:

========================================================== warnings summary ===========================================================
../../../../../../../../usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:28
  /usr/lib/python3.8/site-packages/pytest_aiohttp/plugin.py:28: DeprecationWarning: The 'asyncio_mode' is 'legacy', switching to 'auto'
 for the sake of pytest-aiohttp backward compatibility. Please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest co
nfiguration file.
    config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

In the best case, this is meaningless since the vast majority of these packages don't use aiohttp at all, and therefore shouldn't be setting asyncio_mode in the first place. In the worst, it causes test failures for various packages that expect specific pytest output, in particular pytest plugins.

Example code does not execute

The example code listed on the PyPi page does not run, with multiple errors occurring.

The first is an incorrect await infront of create_app. This has already been fixed in master branch.

Second is DeprecationWarning: The object should be created within an async function with this callstack:

File "/home/eyh46967/dev/pts_webserver/tests/test_temp.py", line 17, in test_hello
    client = await aiohttp_client(create_app())
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/pytest_plugin.py", line 365, in go
    client = TestClient(server, loop=loop, **kwargs)
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/test_utils.py", line 284, in __init__
    cookie_jar = aiohttp.CookieJar(unsafe=True, loop=loop)
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/cookiejar.py", line 67, in __init__
    super().__init__(loop=loop)
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/abc.py", line 145, in __init__
    self._loop = get_running_loop(loop)
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/helpers.py", line 293, in get_running_loop
    stacklevel=3,
DeprecationWarning: The object should be created within an async function

Adding this code to catch the deprecation warnings:

with warnings.catch_warnings():
        warnings.simplefilter("ignore")

Still results in another exception:
RuntimeError: Timeout context manager should be used inside a task

with this callstack:

  File "/home/eyh46967/dev/pts_webserver/tests/test_temp.py", line 20, in test_hello
    resp = await client.get("/")
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/test_utils.py", line 324, in _request
    resp = await self._session.request(method, self.make_url(path), **kwargs)
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/client.py", line 466, in _request
    with timer:
  File "/scratch/eyh46967/pipenv/pts_webserver-v60ZojWY/lib/python3.7/site-packages/aiohttp/helpers.py", line 702, in __enter__
    "Timeout context manager should be used " "inside a task"
RuntimeError: Timeout context manager should be used inside a task

This is running with aiohttp 3.8.1, pytest-aiohttp 0.3.0, on Python 3.7.

every test run twice: pyloop and uvloop

hello! help me, please

my aiohttp application works with uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()

surprisingly every pytest test runs twice: with uvloop and pyloop

@fixture
def client(loop, test_client):
    app = init_app(loop)
    return loop.run_until_complete(test_client(app))

async def test_get(client):
    response = await client.get('v1/accounts/{}'.format(ACCOUNT_ID))
    assert response.status == 200

why?

Tests fail to run with pytest-asyncio==0.18 and asyncio_mode=strict

Prerequisite: Install pytest-asyncio==0.18.0

pytest-aiohttp fails to run tests when the flag asyncio_mode is set to strict in setup.cfg.
Full trace:

../../.pyenv/versions/3.9.9/envs/test-env/lib/python3.9/site-packages/pluggy/_hooks.py:265: in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
../../.pyenv/versions/3.9.9/envs/test-env/lib/python3.9/site-packages/pluggy/_manager.py:80: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../../.pyenv/versions/3.9.9/envs/test-env/lib/python3.9/site-packages/pytest_asyncio/plugin.py:327: in pytest_pycollect_makeitem
    _preprocess_async_fixtures(collector.config, _HOLDER)
../../.pyenv/versions/3.9.9/envs/test-env/lib/python3.9/site-packages/pytest_asyncio/plugin.py:244: in _preprocess_async_fixtures
    assert _has_explicit_asyncio_mark(fixturedef.func)
E   AssertionError: assert False
E    +  where False = _has_explicit_asyncio_mark(<function aiohttp_client at 0x112fa5940>)
E    +    where <function aiohttp_client at 0x112fa5940> = <FixtureDef argname='aiohttp_client' scope='function' baseid=''>.func

Setting the flag asyncio_mode=auto is a functional workaround.

can't use context vars in shutdown

The following test passes but then errors in the finalizers when it tries to run the app shutdown, as the context is no longer available:

from contextvars import ContextVar

import pytest
from aiohttp import web

CV = ContextVar("CV")


async def startup(_app):
    CV.set(1)


async def shutdown(app):
    assert CV.get() == 1


async def handler(request):
    return web.Response(body=str(CV.get()))


@pytest.fixture
def app():
    app = web.Application()
    app.on_startup.append(startup)
    app.on_shutdown.append(shutdown)
    app.add_routes([web.get("/", handler)])
    return app


@pytest.fixture
def client(app, loop, aiohttp_client):
    return loop.run_until_complete(aiohttp_client(app))


async def test_get(client):
    response = await client.get("/")
    assert await response.content.read() == b"1"

Error:

====================================================================================================================== ERRORS =======================================================================================================================
_______________________________________________________________________________________________________ ERROR at teardown of test_get[pyloop] _______________________________________________________________________________________________________

app = <Application 0x104642b60>

    async def shutdown(app):
>       assert CV.get() == 1
E       LookupError: <ContextVar name='CV' at 0x103b27e20>

test_aiohttp_pytest_cv.py:14: LookupError
--------------------------------------------------------------------------------------------------------------- Captured log teardown ---------------------------------------------------------------------------------------------------------------
ERROR    asyncio:base_events.py:1729 Task was destroyed but it is pending!
task: <Task pending name='Task-6' coro=<RequestHandler.start() done, defined at .../lib/python3.10/site-packages/aiohttp/web_protocol.py:464> wait_for=<Future cancelled>>
============================================================================================================== short test summary info ==============================================================================================================
ERROR test_aiohttp_pytest_cv.py::test_get[pyloop] - LookupError: <ContextVar name='CV' at 0x103b27e20>
============================================================================================================ 1 passed, 1 error in 0.03s =============================================================================================================

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.