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

AioHTTPTestCase more async friendly #4732

Merged
merged 13 commits into from
Nov 18, 2020
6 changes: 6 additions & 0 deletions CHANGES/4700.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
AioHTTPTestCase more async friendly
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved

for the people who use unittest and are used to use unittest.TestCase
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved
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`.
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved
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/dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-r lint.txt
-r test.txt
-r doc.txt
asynctest==0.13.0; python_version<"3.8"
WisdomPill marked this conversation as resolved.
Show resolved Hide resolved
cherry_picker==1.3.2; python_version>="3.6"
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
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