diff --git a/tests/conftest.py b/tests/conftest.py index f61c1e94a66..7bf1dc5a6af 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,6 +20,7 @@ from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_seconds from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import LocalTrade, Order, Trade, init_db +from freqtrade.persistence.custom_data import _CustomData from freqtrade.resolvers import ExchangeResolver from freqtrade.system import set_mp_start_method from freqtrade.util import dt_now, dt_ts @@ -581,6 +582,21 @@ def patch_coingecko(mocker) -> None: ) +@pytest.fixture(autouse=True) +def dispose_db_engine(): + """ + Dispose the database engine after each test to release its pooled connection. + Without this, leaked connections accumulate and are finalized at random points + by the GC, emitting ResourceWarnings in unrelated tests. + """ + yield + if (session := getattr(Trade, "session", None)) is not None: + bind = session.get_bind() + session.remove() + _CustomData.session.remove() + bind.dispose() + + @pytest.fixture(scope="function") def init_persistence(default_conf): init_db(default_conf["db_url"]) diff --git a/tests/data/test_entryexitanalysis.py b/tests/data/test_entryexitanalysis.py index 63ac3c1a3b9..8e4c43d55e6 100644 --- a/tests/data/test_entryexitanalysis.py +++ b/tests/data/test_entryexitanalysis.py @@ -13,7 +13,7 @@ @pytest.fixture(autouse=True) -def entryexitanalysis_cleanup() -> None: +def entryexitanalysis_cleanup(): yield None Backtesting.cleanup() diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index ec72f7fb273..cc3c97b7c40 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -1150,7 +1150,10 @@ def test_pandas_warning_direct(ohlcv_history, function, raises, recwarn): # Fixed in 2.2.x getattr(_STRATEGY, function)(df, {"pair": "ETH/BTC"}) else: - assert len(recwarn) == 0, f"warnings: {', '.join(str(w) for w in recwarn.list)}" + # Ignore ResourceWarnings - the GC may clean up resources from + # unrelated tests while this test is running. + warnings = [w for w in recwarn.list if not issubclass(w.category, ResourceWarning)] + assert len(warnings) == 0, f"warnings: {', '.join(str(w) for w in warnings)}" getattr(_STRATEGY, function)(df, {"pair": "ETH/BTC"}) @@ -1159,4 +1162,7 @@ def test_pandas_warning_through_analyze_pair(ohlcv_history, mocker, recwarn): recwarn.clear() mocker.patch.object(_STRATEGY.dp, "ohlcv", return_value=ohlcv_history) _STRATEGY.analyze_pair("ETH/BTC") - assert len(recwarn) == 0, f"warnings: {', '.join(str(w) for w in recwarn.list)}" + # Ignore ResourceWarnings - the GC may clean up resources from + # unrelated tests while this test is running. + warnings = [w for w in recwarn.list if not issubclass(w.category, ResourceWarning)] + assert len(warnings) == 0, f"warnings: {', '.join(str(w) for w in warnings)}"