Skip to content

Commit

Permalink
Deprecate @unittest_run_loop (#5515)
Browse files Browse the repository at this point in the history
* Update unittest docs

* Deprecate decorator code

* Create 5515.misc

* Update test_utils.py

* Whitespace

* Redundant import

* Update testing.rst

* Use correct unittest methods.

* Update testing.rst

* Update test_loop.py

* Adjust stacklevel

* Update test_utils.py

* Test deprecation warning.

* Update test_test_utils.py

* Mark `@unittest_run_loop` as code in changelog

* Update tests/test_test_utils.py

Co-authored-by: Sviatoslav Sydorenko <[email protected]>

* Make `@unittest_run_loop` deprecation message more specific

* Document that the `@unittest_run_loop` decorator is no-op

* Format the lines to be shorter

Co-authored-by: Sam Bull <[email protected]>
Co-authored-by: Sviatoslav Sydorenko <[email protected]>
  • Loading branch information
3 people authored Mar 5, 2021
1 parent 01fdc25 commit 3e588ed
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 38 deletions.
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.
19 changes: 9 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,16 @@ 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 `@unittest_run_loop` is no longer needed in aiohttp 3.8+",
DeprecationWarning,
stacklevel=2,
)
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. It is now a no-op.


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
12 changes: 11 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,17 @@ async def test_get_route() -> None:
await test_get_route()


def test_unittest_run_loop() -> None:
with pytest.warns(
DeprecationWarning,
match=r"Decorator `@unittest_run_loop` is no longer needed in aiohttp 3\.8\+",
):

@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

0 comments on commit 3e588ed

Please sign in to comment.