Skip to content

Commit

Permalink
[3.8] AioHTTPTestCase more async friendly (#4732) (#5257)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Svetlov <[email protected]>.
(cherry picked from commit 5357858)

Co-authored-by: Anas <[email protected]>

Co-authored-by: Anas <[email protected]>
  • Loading branch information
asvetlov and WisdomPill authored Nov 18, 2020
1 parent 493221b commit c7988ad
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 20 deletions.
6 changes: 6 additions & 0 deletions CHANGES/4700.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
AioHTTPTestCase is more async friendly now.

For people who use unittest and are used to use unittest.TestCase
it will be easier to write new test cases like the sync version of the TestCase class,
without using the decorator `@unittest_run_loop`, just `async def test_*`.
The only difference is that for the people using python3.7 and below a new dependency is needed, it is `asynctestcase`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Alexey Stepanov
Amin Etesamian
Amit Tulshyan
Amy Boyle
Anas El Amraoui
Anders Melchiorsen
Andrei Ursulenko
Andrej Antonov
Expand Down
34 changes: 15 additions & 19 deletions aiohttp/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import os
import socket
import sys
import unittest
from abc import ABC, abstractmethod
from types import TracebackType
from typing import TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Type, Union
Expand All @@ -18,17 +17,13 @@
from yarl import URL

import aiohttp
from aiohttp.client import (
ClientResponse,
_RequestContextManager,
_WSRequestContextManager,
)
from aiohttp.client import _RequestContextManager, _WSRequestContextManager

from . import ClientSession, hdrs
from .abc import AbstractCookieJar
from .client_reqrep import ClientResponse
from .client_ws import ClientWebSocketResponse
from .helpers import sentinel
from .helpers import PY_38, sentinel
from .http import HttpVersion, RawRequestMessage
from .signals import Signal
from .web import (
Expand All @@ -48,6 +43,10 @@
else:
SSLContext = None

if PY_38:
from unittest import IsolatedAsyncioTestCase as TestCase
else:
from asynctest import TestCase # type: ignore

REUSE_ADDRESS = os.name == "posix" and sys.platform != "cygwin"

Expand Down Expand Up @@ -400,7 +399,7 @@ async def __aexit__(
await self.close()


class AioHTTPTestCase(unittest.TestCase):
class AioHTTPTestCase(TestCase):
"""A base class to allow for unittest web applications using
aiohttp.
Expand Down Expand Up @@ -434,26 +433,23 @@ def get_app(self) -> Application:
raise RuntimeError("Did you forget to define get_application()?")

def setUp(self) -> None:
self.loop = setup_test_loop()

self.app = self.loop.run_until_complete(self.get_application())
self.server = self.loop.run_until_complete(self.get_server(self.app))
self.client = self.loop.run_until_complete(self.get_client(self.server))

self.loop.run_until_complete(self.client.start_server())
if PY_38:
self.loop = asyncio.get_event_loop()

self.loop.run_until_complete(self.setUpAsync())

async def setUpAsync(self) -> None:
pass
self.app = await self.get_application()
self.server = await self.get_server(self.app)
self.client = await self.get_client(self.server)

await self.client.start_server()

def tearDown(self) -> None:
self.loop.run_until_complete(self.tearDownAsync())
self.loop.run_until_complete(self.client.close())
teardown_test_loop(self.loop)

async def tearDownAsync(self) -> None:
pass
await self.client.close()

async def get_server(self, app: Application) -> TestServer:
"""Return a TestServer instance."""
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
aiodns==2.0.0; sys_platform=="linux" or sys_platform=="darwin" and python_version>="3.7"
async-generator==1.10
async-timeout==3.0.1
asynctest==0.13.0; python_version<"3.8"
attrs==20.3.0
brotlipy==0.7.0
cchardet==2.1.7
Expand Down
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,7 @@ ignore_missing_imports = true

[mypy-idna_ssl]
ignore_missing_imports = true


[mypy-asynctest]
ignore_missing_imports = true
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def build_extension(self, ext):
"chardet>=2.0,<4.0",
"multidict>=4.5,<7.0",
"async_timeout>=3.0,<4.0",
'asynctest==0.13.0; python_version<"3.8"',
"yarl>=1.0,<2.0",
'idna-ssl>=1.0; python_version<"3.7"',
"typing_extensions>=3.6.5",
Expand Down
17 changes: 16 additions & 1 deletion tests/test_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ async def test_example_with_loop(self) -> None:
text = await request.text()
assert _hello_world_str == text

def test_example(self) -> None:
def test_inner_example(self) -> None:
async def test_get_route() -> None:
resp = await self.client.request("GET", "/")
assert resp.status == 200
Expand All @@ -118,6 +118,21 @@ async def test_get_route() -> None:

self.loop.run_until_complete(test_get_route())

async def test_example_without_explicit_loop(self) -> None:
request = await self.client.request("GET", "/")
assert request.status == 200
text = await request.text()
assert _hello_world_str == text

async def test_inner_example_without_explicit_loop(self) -> None:
async def test_get_route() -> None:
resp = await self.client.request("GET", "/")
assert resp.status == 200
text = await resp.text()
assert _hello_world_str == text

await test_get_route()


def test_get_route(loop, test_client) -> None:
async def test_get_route() -> None:
Expand Down

0 comments on commit c7988ad

Please sign in to comment.