【问题标题】:Save A Reloaded Python Module For Testing Purposes保存重新加载的 Python 模块以进行测试
【发布时间】:2014-01-29 22:32:59
【问题描述】:

我有一个我正在测试的 Python 模块,并且由于模块的工作方式(它在导入时进行一些初始化)在每个测试初始化​​的unittest 期间重新加载模块。 reload 是在setUp 方法中完成的,所以所有测试实际上都是在重新加载模块,这很好。

如果我只在任何给定的 Python 会话期间在该文件中运行测试,这一切都很好,因为我从不需要对模块的前一个实例的引用。但是当我使用 Pydev 或unittestdiscover 时,我得到了here 所见的错误,因为导入此模块的其他测试已经失去了对模块中对象的引用,因为它们是在我的所有重新加载业务之前导入的测试。

围绕 SO 有类似的问题,例如 this one,但这些问题都涉及在重新加载后更新对象。我想做的是在初始导入后保存模块的状态,运行我的测试来完成所有重新加载,然后在测试tearDown 中放回对模块的初始引用,以便运行测试使用该模块的下游仍然有正确的参考。请注意,我没有对模块进行任何更改,我只是重新加载它以测试它所做的一些初始化部分。

还有一些解决方案在模块代码中包含我不感兴趣的钩子。我不想要求开发人员将内容推送到代码库中以便测试可以运行。我正在使用 Python 2.6 和 unittest。我看到有些项目存在,例如process-isolation,虽然我不确定这是否完全符合我的要求,但它不适用于 Python 2.6,如果可能的话,我不想将新包添加到我们的堆栈中。存根代码如下:

import mypackage.mymodule
saved_module = mypackage.mymodule

class SomeTestThatReloads(unittest.TestCase):
    def setUp(self):
        reload(mypackage.mymodule)

    def tearDown(self):
        # What to do here with saved_module?

    def test_initialization(self):
        # testing scenario code

【问题讨论】:

    标签: python reload python-2.6 python-2.x python-unittest


    【解决方案1】:

    不幸的是,没有简单的方法可以做到这一点。如果你的模块初始化有副作用(从外观上看确实有——钩子等),没有自动的方法来撤销它们,除非完全重新启动 Python 进程。

    同样,如果您的代码中的任何内容从您的模块而不是模块本身导入某些内容(例如,from my_package.my_module import some_object 而不是import my_package.my_module),重新加载模块不会对导入的对象做任何事情(some_object 将引用到执行 import 语句时提到的 my_package.my_module.some_object 所指的任何内容,无论您重新加载什么以及磁盘上有什么)。

    这一切归结为的问题是 Python 的模块系统通过执行模块(充满副作用,类/函数/变量的定义只是众多模块之一)然后公开顶级变量来工作他们创建的,Python VM 本身将模块视为一大块没有隔离的全局状态。

    因此,您的问题的一般解决方案是在每次测试后重新启动一个新的 Python 进程(这很糟糕:()。

    如果您的模块的初始化副作用有限,您可以尝试使用 Nose 而不是 Unittest 运行测试(测试是兼容的,您无需重写任何内容),其 Isolate 插件会尝试执行您想要的操作: http://nose.readthedocs.org/en/latest/plugins/isolate.html

    但由于我上面所说的,它不能保证在一般情况下有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2011-11-27
      • 2010-10-01
      相关资源
      最近更新 更多