Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate @unittest_run_loop #5515

Merged
merged 19 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/5515.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate ``@unittest_run_loop``. This behaviour is now the default.
17 changes: 7 additions & 10 deletions aiohttp/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import asyncio
import contextlib
import functools
import gc
import inspect
import os
import socket
import sys
import warnings
from abc import ABC, abstractmethod
from types import TracebackType
from typing import (
Expand Down Expand Up @@ -472,17 +472,14 @@ async def get_client(self, server: TestServer) -> TestClient:

def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any:
"""A decorator dedicated to use with asynchronous methods of an
AioHTTPTestCase.
AioHTTPTestCase in aiohttp <3.8.

Handles executing an asynchronous function, using
the self.loop of the AioHTTPTestCase.
In 3.8+, this does nothing.
"""

@functools.wraps(func, *args, **kwargs)
def new_func(self: Any, *inner_args: Any, **inner_kwargs: Any) -> Any:
return self.loop.run_until_complete(func(self, *inner_args, **inner_kwargs))

return new_func
warnings.warn(
"Decorator no longer needed in 3.8+", DeprecationWarning, stacklevel=2
webknjaz marked this conversation as resolved.
Show resolved Hide resolved
)
return func


_LOOP_FACTORY = Callable[[], asyncio.AbstractEventLoop]
Expand Down
36 changes: 11 additions & 25 deletions docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ Unittest
To test applications with the standard library's unittest or unittest-based
functionality, the AioHTTPTestCase is provided::

from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from aiohttp.test_utils import AioHTTPTestCase
from aiohttp import web

class MyAppTestCase(AioHTTPTestCase):
Expand All @@ -259,26 +259,11 @@ functionality, the AioHTTPTestCase is provided::
app.router.add_get('/', hello)
return app

# the unittest_run_loop decorator can be used in tandem with
# the AioHTTPTestCase to simplify running
# tests that are asynchronous
@unittest_run_loop
async def test_example(self):
resp = await self.client.request("GET", "/")
assert resp.status == 200
text = await resp.text()
assert "Hello, world" in text

# a vanilla example
def test_example_vanilla(self):
async def test_get_route():
url = "/"
resp = await self.client.request("GET", url)
assert resp.status == 200
async with self.client.request("GET", "/") as resp:
self.assertEqual(resp.status, 200)
text = await resp.text()
assert "Hello, world" in text

self.loop.run_until_complete(test_get_route())
self.assertIn("Hello, world", text)

.. class:: AioHTTPTestCase

Expand Down Expand Up @@ -361,16 +346,13 @@ functionality, the AioHTTPTestCase is provided::
.. note::

The ``TestClient``'s methods are asynchronous: you have to
execute function on the test client using asynchronous methods.

A basic test class wraps every test method by
:func:`unittest_run_loop` decorator::
execute functions on the test client using asynchronous methods.::

class TestA(AioHTTPTestCase):

@unittest_run_loop
async def test_f(self):
resp = await self.client.get('/')
async with self.client.get('/') as resp:
body = await resp.text()


.. decorator:: unittest_run_loop:
Expand All @@ -381,6 +363,10 @@ functionality, the AioHTTPTestCase is provided::
Handles executing an asynchronous function, using
the :attr:`AioHTTPTestCase.loop` of the :class:`AioHTTPTestCase`.

.. deprecated:: 3.8
In 3.8+ :class:`AioHTTPTestCase` inherits from :class:`unittest.IsolatedAsyncioTestCase`
making this decorator unneeded.
webknjaz marked this conversation as resolved.
Show resolved Hide resolved


Faking request object
---------------------
Expand Down
3 changes: 1 addition & 2 deletions tests/test_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest

from aiohttp import web
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from aiohttp.test_utils import AioHTTPTestCase


@pytest.mark.skipif(
Expand All @@ -31,7 +31,6 @@ async def get_application(self):
async def on_startup_hook(self, app):
self.on_startup_called = True

@unittest_run_loop
async def test_on_startup_hook(self) -> None:
self.assertTrue(self.on_startup_called)

Expand Down
9 changes: 8 additions & 1 deletion tests/test_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ class TestAioHTTPTestCase(AioHTTPTestCase):
def get_app(self):
return _create_example_app()

@unittest_run_loop
async def test_example_with_loop(self) -> None:
request = await self.client.request("GET", "/")
assert request.status == 200
Expand Down Expand Up @@ -134,6 +133,14 @@ async def test_get_route() -> None:
await test_get_route()


def test_unittest_run_loop() -> None:
with pytest.warns(DeprecationWarning):
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved

@unittest_run_loop
def foo():
pass


def test_get_route(loop, test_client) -> None:
async def test_get_route() -> None:
resp = await test_client.request("GET", "/")
Expand Down