我有一些使用多处理的代码。池来分叉工人并并行执行任务。我正试图找到正确的方法来运行此代码的单元测试。
注意我是不是尝试并行测试串行代码测试用例,我知道像nose支持这样的包。
如果我写一个测试函数来测试并行代码,并尝试使用nose通过:nosetests tests/test_function.py
运行测试,非并行测试执行正确,但并行测试失败时,multiprocessing试图分叉,因为main不可导入:
File "C:python-2.7.10.amd64libmultiprocessingforking.py", line 488, in prepare
assert main_name not in sys.modules, main_name
AssertionError: __main__
assert main_name not in sys.modules, main_name
AssertionError: _assert main_name not in sys.modules, main_name
_main__AssertionError
: __main__
它只是重复,直到我终止任务。如果将tests/test_function.py
修改为包含以下内容,则可以成功运行测试:
if __name__ == '__main__':
import nose
nose.main()
然后用python teststest_function.py
执行那么,什么是"正确"的方法来做这件事,将集成到一个单元测试包(不必是鼻子)?
Environ: Python 2.7.10 amd64 on Windows 7 64位
更新2020:使用python 3和pytest,这不是问题,建议升级!
我更喜欢在单元测试中使用python mock模拟多处理。因为单元测试应该是独立的和可重复的。这就是为什么我通常创建多处理类(Process
和Pool
)的模拟版本。只是为了确保我的测试以正确的方式执行
看起来像(参见http://7fttallrussian.blogspot.com/2014/04/fix-for-bug-with-unittest-and.html)
在2.7.6之前的所有python中都有一个错误(即所有2.7.6)。x到目前为止, 2014年4月17日),打破使用单元测试和多处理模块在Windows. ...在新的python 3中修复了这个问题。X,但尚未反向移植到2。
我看到有人建议:
- patch multiprocessing模块本身(来自第一个链接的博文有一个到补丁的链接)。我目前不能在这里发布两个以上的链接)
- 或在测试模块中实现类似的解决方案:测试 中的解决方案示例
来自"测试中的变通示例"的代码(未显著修改):
import unittest
import sys
class TestSample(unittest.TestCase):
def test(self):
# To fix the Windows forking system it's necessary to point __main__ to
# the module we want to execute in the forked process
old_main = sys.modules["__main__"]
old_main_file = sys.modules["__main__"].__file__
sys.modules["__main__"] = sys.modules["app"]
sys.modules["__main__"].__file__ = sys.modules["app"].__file__
# do your testing here
sys.modules["__main__"] = old_main
sys.modules["__main__"].__file__ = old_main_file
免责声明:我没有亲自尝试过这两种解决方案(至少到目前为止)。我在试图解决不同的问题时,遇到了他们和这个问题。如果我尝试了这些解决方案中的任何一个,我将修改这篇文章。