feat: improve async testing infrastructure and fix coroutine warnings (issue #84)
## Key Improvements: ### Enhanced Test Configuration - Add pytest-asyncio with auto mode for better async test support - Remove manual event loop fixture in favor of pytest-asyncio management - Configure proper asyncio mode in pytest.ini ### New Async Test Utilities - Add AsyncTestCase base class for automatic mock cleanup - Add create_async_mock_that_returns/raises helper functions - Add cleanup_async_mocks function to prevent resource warnings - Add async_cleanup fixture for test-scoped mock management ### Fixed Coroutine Warnings - Update TestGiteaPluginListIssues to inherit from AsyncTestCase - Replace problematic AsyncMock usage with managed async mocks - Mock async methods directly on plugin instances to avoid creating real coroutines - Significantly reduced coroutine warnings in test_issue_59_gitea_plugin.py ### Results - Reduced coroutine warnings from 11+ to ~3 remaining (75%+ improvement) - All existing tests continue to pass - Better async test patterns established for future development - Proper resource cleanup prevents memory leaks in test runs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,13 +14,12 @@ from typing import Generator, Dict, Any
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
# Import async test utilities
|
||||
from tests.utils.assertions import cleanup_async_mocks, create_async_mock_that_returns
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def event_loop():
|
||||
"""Create an instance of the default event loop for the test session."""
|
||||
loop = asyncio.new_event_loop()
|
||||
yield loop
|
||||
loop.close()
|
||||
|
||||
# Note: event_loop fixture is now handled by pytest-asyncio with asyncio_mode=auto
|
||||
# This replaces the manual event loop management for better async test support
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
@@ -261,6 +260,44 @@ def async_test_timeout():
|
||||
return 30.0 # 30 seconds
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def async_cleanup():
|
||||
"""Fixture to help with async test cleanup and prevent coroutine warnings."""
|
||||
mocks_to_cleanup = []
|
||||
|
||||
def register_mock(mock):
|
||||
"""Register a mock for cleanup."""
|
||||
mocks_to_cleanup.append(mock)
|
||||
return mock
|
||||
|
||||
yield register_mock
|
||||
|
||||
# Cleanup all registered mocks
|
||||
cleanup_async_mocks(*mocks_to_cleanup)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def async_mock_client(async_cleanup):
|
||||
"""Provide a properly configured async HTTP client mock."""
|
||||
mock_client = AsyncMock()
|
||||
mock_response = AsyncMock()
|
||||
mock_response.status = 200
|
||||
mock_response.json = create_async_mock_that_returns({"status": "success"})
|
||||
mock_response.text = create_async_mock_that_returns('{"status": "success"}')
|
||||
|
||||
# Configure the mock client methods
|
||||
mock_client.get = create_async_mock_that_returns(mock_response)
|
||||
mock_client.post = create_async_mock_that_returns(mock_response)
|
||||
mock_client.put = create_async_mock_that_returns(mock_response)
|
||||
mock_client.delete = create_async_mock_that_returns(mock_response)
|
||||
|
||||
# Register for cleanup
|
||||
async_cleanup(mock_client)
|
||||
async_cleanup(mock_response)
|
||||
|
||||
return mock_client
|
||||
|
||||
|
||||
# Test markers configuration
|
||||
def pytest_configure(config):
|
||||
"""Configure pytest markers."""
|
||||
|
||||
Reference in New Issue
Block a user