在Python中使用辅助函数对ABC进行单元测试
我想知道是否有可能在Python的测试环境中更改helper函数。我的应用程序结构如下:在Python中使用辅助函数对ABC进行单元测试,python,unit-testing,pytest,helpers,Python,Unit Testing,Pytest,Helpers,我想知道是否有可能在Python的测试环境中更改helper函数。我的应用程序结构如下: app/ trader/ __init__.py strategies/ __init__.py base_strategy.py util.py models/ __init__.py base_model.py tests/ __init__.py strategies/
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
文件中,有一个helper函数,它查看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
-类中,我有一个方法,它使用现有的\u alpha\u 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
目录中,因此也不在现有的α模型列表中注册。当我想用pytest测试ABC的功能时,很多测试都失败了,因为检查模型可用性的方法失败了。一个简单的解决方案是将存根类放在我的应用程序的trader
目录中,但我宁愿将我的测试代码与应用程序的其余部分分开。我可能还可以将现有的\u alpha\u模型
作为基类的一个属性,但我并不认为这样做有什么意义,只是让测试通过了。有没有一种方法可以将存根类注入到现有的单元测试的_alpha_模型中
,这样在不太改变基类的情况下,ABC的测试不会失败
--------------编辑-------------------
我现在有两个工作版本的测试代码。一个是使用@hoefling的verison,我只需将alpha\u模型添加到现有的alpha\u模型列表中即可:
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_模型
模块,并重新加载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个版本的特定模块,而在生产环境中并非如此。这是一个好主意,还是应该将其保留在测试环境的第一个版本中?现有的\u alpha\u模型。append('foo')
?这不起作用,因为现有的\u alpha\u模型是在初始化过程中创建和填充的,据我所知,不是在测试类的名称空间中。我也不知道如何在运行时访问BaseTradingStrategy
使用的实例。你说的初始化是什么意思?至于名称空间-您认为Python会在每次导入时创建现有的\u alpha\u模型的新共享副本吗?只需做一个简单的测试,比如从util导入现有的_alpha_模型作为数据;data.append('spam');s=MyStrategy();s、 注册_model('spam')
以验证其是否有效,然后。要访问BaseStrategy
使用的“实例”,请从trader.strategys.base_strategy导入现有的_alpha_models
。将其与从trader.strategies.util import existing_alpha_models导入的列表进行比较,您将看到它是第一次导入时初始化的同一个实例,然后缓存并重新用于所有后续导入。好吧,那么我的知识就错了。我认为这会更复杂,对于基类中的子导入,会创建列表的额外实例,我无法简单地访问这些实例。谢谢你帮我澄清。如果你想创造一个答案,我会接受的。