Skip to content

Commit

Permalink
AioHTTPTestCase more async friendly (aio-libs#4732)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Svetlov <andrew.svetlov@gmail.com>
  • Loading branch information
2 people authored and commonism committed Apr 27, 2021
1 parent 49e3b48 commit 046dbae
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 @@ -9,7 +9,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 @@ -19,17 +18,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 @@ -49,6 +44,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 @@ -386,7 +385,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 @@ -420,26 +419,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 @@ -2,6 +2,7 @@
# required c-ares will not build on windows and has build problems on Macos Python<3.7
aiodns==2.0.0; sys_platform=="linux" or sys_platform=="darwin" and python_version>="3.7"
async-timeout==4.0.0a3
asynctest==0.13.0; python_version<"3.8"
attrs==20.3.0
Brotli==1.0.9
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 @@ -97,3 +97,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 @@ -55,6 +55,7 @@
"chardet>=2.0,<4.0",
"multidict>=4.5,<7.0",
"async_timeout>=4.0a2,<5.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 @@ -95,7 +95,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 @@ -104,6 +104,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 046dbae

Please sign in to comment.