From 6db3778c6fd57535f055465468eb93c3ee0d455e Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Wed, 26 Oct 2022 22:21:04 +0300 Subject: [PATCH] Tests on Python 3.11 (#1044) * Try to use Python 3.11 * Remove `asynctest` dependency * Fixed aiofiles tests * Added changelog --- .github/workflows/tests.yml | 2 +- CHANGES/1044.misc.rst | 1 + poetry.lock | 14 +------------ pyproject.toml | 1 - tests/test_api/test_client/test_bot.py | 19 +++++++---------- .../test_session/test_aiohttp_session.py | 15 +++++-------- .../test_session/test_base_session.py | 9 ++------ tests/test_dispatcher/test_dispatcher.py | 21 +++++++------------ .../test_dispatcher/test_event/test_event.py | 9 ++------ tests/test_filters/test_base.py | 9 ++------ tests/test_utils/test_chat_action.py | 15 +++++-------- tests/test_webhook/test_aiohtt_server.py | 9 ++------ 12 files changed, 36 insertions(+), 88 deletions(-) create mode 100644 CHANGES/1044.misc.rst diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bfe852b5..e94e89d3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: - '3.8' - '3.9' - '3.10' - #- '3.11' + - '3.11' - 'pypy3.8' - 'pypy3.9' diff --git a/CHANGES/1044.misc.rst b/CHANGES/1044.misc.rst new file mode 100644 index 00000000..ef356e5a --- /dev/null +++ b/CHANGES/1044.misc.rst @@ -0,0 +1 @@ +Enabled testing on Python 3.11 diff --git a/poetry.lock b/poetry.lock index d4e793ca..87c98e40 100644 --- a/poetry.lock +++ b/poetry.lock @@ -78,14 +78,6 @@ category = "main" optional = false python-versions = ">=3.6" -[[package]] -name = "asynctest" -version = "0.13.0" -description = "Enhance the standard unittest package with features for testing asyncio libraries" -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "attrs" version = "22.1.0" @@ -1203,7 +1195,7 @@ redis = ["redis"] [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "ee5c55fdf1dfa75f942e6a26c5a7d6111a2c8eb313ac9850097fb2b951e5aa64" +content-hash = "96a502ce3830054d2b1f248f21b710d172b9c5c3bf8943e19f7478a0586dfcf5" [metadata.files] aiofiles = [ @@ -1319,10 +1311,6 @@ async-timeout = [ {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] -asynctest = [ - {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, - {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, -] attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, diff --git a/pyproject.toml b/pyproject.toml index 9c016d66..059db6e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,6 @@ pytest-mypy = "^0.10.0" pytest-cov = "^4.0.0" pytest-aiohttp = "^1.0.4" aresponses = "^2.1.6" -asynctest = "^0.13.0" [tool.poetry.group.dev.dependencies] diff --git a/tests/test_api/test_client/test_bot.py b/tests/test_api/test_client/test_bot.py index d2c9d56a..7266bdcd 100644 --- a/tests/test_api/test_client/test_bot.py +++ b/tests/test_api/test_client/test_bot.py @@ -1,6 +1,7 @@ import io import os from tempfile import mkstemp +from unittest.mock import AsyncMock, MagicMock, patch import aiofiles import pytest @@ -13,12 +14,6 @@ from aiogram.methods import GetFile, GetMe from aiogram.types import File, PhotoSize from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -44,7 +39,7 @@ class TestBot: with patch( "aiogram.client.session.aiohttp.AiohttpSession.make_request", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_make_request: await bot(method) mocked_make_request.assert_awaited_with(bot, method, timeout=None) @@ -55,7 +50,7 @@ class TestBot: await session.create_session() with patch( - "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock + "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock ) as mocked_close: await bot.session.close() mocked_close.assert_awaited() @@ -63,7 +58,7 @@ class TestBot: @pytest.mark.parametrize("close", [True, False]) async def test_context_manager(self, close: bool): with patch( - "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock + "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock ) as mocked_close: async with Bot("42:TEST", session=AiohttpSession()).context(auto_close=close) as bot: assert isinstance(bot, Bot) @@ -78,11 +73,11 @@ class TestBot: ) # https://github.com/Tinche/aiofiles#writing-tests-for-aiofiles - aiofiles.threadpool.wrap.register(CoroutineMock)( - lambda *args, **kwargs: aiofiles.threadpool.AsyncBufferedIOBase(*args, **kwargs) + aiofiles.threadpool.wrap.register(MagicMock)( + lambda *args, **kwargs: aiofiles.threadpool.binary.AsyncBufferedIOBase(*args, **kwargs) ) - mock_file = CoroutineMock() + mock_file = MagicMock() bot = Bot("42:TEST") with patch("aiofiles.threadpool.sync_open", return_value=mock_file): diff --git a/tests/test_api/test_client/test_session/test_aiohttp_session.py b/tests/test_api/test_client/test_session/test_aiohttp_session.py index 291991be..6dbf213c 100644 --- a/tests/test_api/test_client/test_session/test_aiohttp_session.py +++ b/tests/test_api/test_client/test_session/test_aiohttp_session.py @@ -1,5 +1,6 @@ import asyncio from typing import AsyncContextManager, AsyncGenerator +from unittest.mock import AsyncMock, patch import aiohttp_socks import pytest @@ -14,12 +15,6 @@ from aiogram.methods import Request, TelegramMethod from aiogram.types import UNSET, InputFile from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -106,7 +101,7 @@ class TestAiohttpSession: session = AiohttpSession() await session.create_session() - with patch("aiohttp.ClientSession.close", new=CoroutineMock()) as mocked_close: + with patch("aiohttp.ClientSession.close", new=AsyncMock()) as mocked_close: await session.close() mocked_close.assert_called_once() @@ -184,7 +179,7 @@ class TestAiohttpSession: with patch( "aiohttp.client.ClientSession._request", - new_callable=CoroutineMock, + new_callable=AsyncMock, side_effect=side_effect, ): with pytest.raises(TelegramNetworkError): @@ -215,9 +210,9 @@ class TestAiohttpSession: with patch( "aiogram.client.session.aiohttp.AiohttpSession.create_session", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_create_session, patch( - "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock + "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock ) as mocked_close: async with session as ctx: assert session == ctx diff --git a/tests/test_api/test_client/test_session/test_base_session.py b/tests/test_api/test_client/test_session/test_base_session.py index 04de5259..dbb578a1 100644 --- a/tests/test_api/test_client/test_session/test_base_session.py +++ b/tests/test_api/test_client/test_session/test_base_session.py @@ -1,6 +1,7 @@ import datetime import json from typing import AsyncContextManager, AsyncGenerator, Optional +from unittest.mock import AsyncMock, patch import pytest @@ -25,12 +26,6 @@ from aiogram.methods import DeleteMessage, GetMe, TelegramMethod from aiogram.types import UNSET, User from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -227,7 +222,7 @@ class TestBaseSession: with patch( "tests.test_api.test_client.test_session.test_base_session.CustomSession.close", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_close: async with session as ctx: assert session == ctx diff --git a/tests/test_dispatcher/test_dispatcher.py b/tests/test_dispatcher/test_dispatcher.py index c1dd05fc..5f06ef52 100644 --- a/tests/test_dispatcher/test_dispatcher.py +++ b/tests/test_dispatcher/test_dispatcher.py @@ -4,6 +4,7 @@ import time import warnings from collections import Counter from typing import Any +from unittest.mock import AsyncMock, patch import pytest @@ -33,12 +34,6 @@ from aiogram.types import ( from aiogram.types.error_event import ErrorEvent from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -176,7 +171,7 @@ class TestDispatcher: bot.add_result_for(GetUpdates, ok=False, error_code=500, description="restarting") with patch( "aiogram.utils.backoff.Backoff.asleep", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_asleep: assert isinstance(await anext(listen), Update) assert mocked_asleep.awaited @@ -594,7 +589,7 @@ class TestDispatcher: with patch( "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_silent_call_request: result = await dispatcher._process_update(bot=bot, update=Update(update_id=42)) print(result) @@ -620,7 +615,7 @@ class TestDispatcher: yield Update(update_id=42) with patch( - "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=CoroutineMock + "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=AsyncMock ) as mocked_process_update, patch( "aiogram.dispatcher.dispatcher.Dispatcher._listen_updates" ) as patched_listen_updates: @@ -682,11 +677,11 @@ class TestDispatcher: yield Update(update_id=42) with patch( - "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=CoroutineMock + "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=AsyncMock ) as mocked_process_update, patch( - "aiogram.dispatcher.router.Router.emit_startup", new_callable=CoroutineMock + "aiogram.dispatcher.router.Router.emit_startup", new_callable=AsyncMock ) as mocked_emit_startup, patch( - "aiogram.dispatcher.router.Router.emit_shutdown", new_callable=CoroutineMock + "aiogram.dispatcher.router.Router.emit_shutdown", new_callable=AsyncMock ) as mocked_emit_shutdown, patch( "aiogram.dispatcher.dispatcher.Dispatcher._listen_updates" ) as patched_listen_updates: @@ -722,7 +717,7 @@ class TestDispatcher: with patch( "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_silent_call_request: response = await dispatcher.feed_webhook_update(bot, RAW_UPDATE, _timeout=0.1) assert response is None diff --git a/tests/test_dispatcher/test_event/test_event.py b/tests/test_dispatcher/test_event/test_event.py index 735c498b..c8f32212 100644 --- a/tests/test_dispatcher/test_event/test_event.py +++ b/tests/test_dispatcher/test_event/test_event.py @@ -1,17 +1,12 @@ import functools from typing import Any +from unittest.mock import AsyncMock, patch import pytest from aiogram.dispatcher.event.event import EventObserver from aiogram.dispatcher.event.handler import HandlerObject -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -54,7 +49,7 @@ class TestEventObserver: with patch( "aiogram.dispatcher.event.handler.CallableMixin.call", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_my_handler: results = await observer.trigger("test") assert results is None diff --git a/tests/test_filters/test_base.py b/tests/test_filters/test_base.py index 904c14b1..82780c56 100644 --- a/tests/test_filters/test_base.py +++ b/tests/test_filters/test_base.py @@ -1,15 +1,10 @@ from typing import Awaitable +from unittest.mock import AsyncMock, patch import pytest from aiogram.filters import Filter -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - pytestmark = pytest.mark.asyncio @@ -26,7 +21,7 @@ class TestBaseFilter: with patch( "tests.test_filters.test_base.MyFilter.__call__", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_call: call = my_filter(event="test") await call diff --git a/tests/test_utils/test_chat_action.py b/tests/test_utils/test_chat_action.py index caf05e33..21182968 100644 --- a/tests/test_utils/test_chat_action.py +++ b/tests/test_utils/test_chat_action.py @@ -1,6 +1,7 @@ import asyncio import time from datetime import datetime +from unittest.mock import AsyncMock, patch import pytest @@ -10,13 +11,7 @@ from aiogram.types import Chat, Message, User from aiogram.utils.chat_action import ChatActionMiddleware, ChatActionSender from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - -pytestmarm = pytest.mark.asyncio +pytestmark = pytest.mark.asyncio class TestChatActionSender: @@ -55,7 +50,7 @@ class TestChatActionSender: async def test_worker(self, bot: Bot): with patch( "aiogram.client.bot.Bot.send_chat_action", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_send_chat_action: async with ChatActionSender.typing( bot=bot, chat_id=42, interval=0.01, initial_sleep=0 @@ -101,10 +96,10 @@ class TestChatActionMiddleware: middleware = ChatActionMiddleware() with patch( "aiogram.utils.chat_action.ChatActionSender._run", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_run, patch( "aiogram.utils.chat_action.ChatActionSender._stop", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_stop: data = {"handler": HandlerObject(callback=handler1), "bot": bot} message = Message( diff --git a/tests/test_webhook/test_aiohtt_server.py b/tests/test_webhook/test_aiohtt_server.py index ceb24243..5c9cbcc8 100644 --- a/tests/test_webhook/test_aiohtt_server.py +++ b/tests/test_webhook/test_aiohtt_server.py @@ -3,6 +3,7 @@ import time from asyncio import Event from dataclasses import dataclass from typing import Any, Dict +from unittest.mock import AsyncMock, patch import pytest from aiohttp import web @@ -21,12 +22,6 @@ from aiogram.webhook.aiohttp_server import ( from aiogram.webhook.security import IPFilter from tests.mocked_bot import MockedBot -try: - from asynctest import CoroutineMock, patch -except ImportError: - from unittest.mock import AsyncMock as CoroutineMock # type: ignore - from unittest.mock import patch - class TestAiohttpServer: def test_setup_application(self): @@ -110,7 +105,7 @@ class TestSimpleRequestHandler: handler.handle_in_background = True with patch( "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", - new_callable=CoroutineMock, + new_callable=AsyncMock, ) as mocked_silent_call_request: handler_event.clear() resp = await self.make_reqest(client=client)