使用Python中的辅助函数对ABC进行单元测试

时间:2018-05-04 10:03:35

标签: python unit-testing pytest helpers

我想知道是否可以在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个版本的某些模块,但事实并非如此。生产环境。这是一个好主意,还是应该将它留在我测试环境的第一个版本中?

0 个答案:

没有答案
相关问题