我想知道是否可以在Python的测试环境中更改辅助函数。我的应用程序结构如下:
app/
trader/
__init__.py
strategies/
__init__.py
base_strategy.py
util.py
models/
__init__.py
base_model.py
tests/
__init__.py
strategies/
__init__.py
stub_strategy.py
test_strategies.py
models/
__init__.py
stub_model.py
其中每个base_*.py
是一个抽象基类,它继承自tests目录中的每个stub_*.py
文件。在我的util.py
文件中,有一个帮助函数,它可以查看trader/strategies/models
目录并注册所有可用的模型:
import inspect
from . import alpha_models
existing_alpha_models = []
alpha_model_dict = {}
for name, obj in inspect.getmembers(alpha_models):
if inspect.isclass(obj):
existing_alpha_models.append(name)
alpha_model_dict[name] = obj
现在我的问题:在我的BaseTradingStrategy
- 类中,我有一个使用existing_alpha_models
列表的方法来检查模型是否存在。
from abc import ABC, abstractmethod
from .util import existing_alpha_models
class BaseTradingStrategy(ABC):
"""BaseTrading Code comes here"""
@abstractmethod
def some_abs_method(self):
raise NotImplementedError
def register_model(self, model_name):
if model_name not in existing_alpha_models:
raise ValueError
对于单元测试,我创建了存根类,它们不在trader/strategies/models
目录中,因此未在existing_alpha_models
列表中注册。当我想用pytest测试ABC的功能时,许多测试都失败了,因为检查模型可用性的方法失败了。一个简单的解决方案是将存根类放在我的应用程序的trader
目录中,但我宁愿将我的测试代码与应用程序的其余部分分开。我可能也可以使existing_alpha_models
成为基类的属性,但除了让测试通过之外,我并没有真正看到这样做的重点。有没有办法在existing_alpha_models
中注入存根类进行单元测试,这样ABC的测试不会失败而不会过多地更改基类?
-------------- EDIT -------------------
我现在有2个工作版本的测试代码。一个是使用@hoefling的版本,我只需将alpha_models
添加到existing_alpha_models
列表中:
from tests.strategies import StubTradingStrategy
from tests.strategies.alpha_models import StubModel, StubModel2, StubModel3
from trader.strategies.util import existing_alpha_models
existing_alpha_models.extend(["StubModel", "StubModel2", "StubModel3"])
和一个版本,我将模型添加到alpha_models
模块并重新加载2个模块:
import importlib
from trader.strategies import alpha_models
from tests.strategies.alpha_models import StubModel, StubModel2, StubModel3
setattr(alpha_models, "StubModel", StubModel)
setattr(alpha_models, "StubModel2", StubModel2)
setattr(alpha_models, "StubModel3", StubModel3)
from nutrader.strategies import util
import nutrader.strategies.base_strategy
importlib.reload(util)
importlib.reload(nutrader.strategies.base_strategy)
from tests.strategies import StubTradingStrategy
第二个版本的优点是它允许我实际测试util
代码,但它也在我的测试代码中引入了潜在的风险,因为存在2个版本的某些模块,但事实并非如此。生产环境。这是一个好主意,还是应该将它留在我测试环境的第一个版本中?