Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按顺序运行时,Python单元测试和多处理失败_Python_Linux_Python 2.7_Unit Testing - Fatal编程技术网

按顺序运行时,Python单元测试和多处理失败

按顺序运行时,Python单元测试和多处理失败,python,linux,python-2.7,unit-testing,Python,Linux,Python 2.7,Unit Testing,我正在尝试为使用多个进程的应用程序创建unittests,但在尝试同时运行所有测试时遇到了奇怪的问题。基本上,当单独运行测试时,它们会毫无问题地通过,但当按顺序运行时,例如运行文件中的所有测试时,某些测试将失败 我所看到的是,许多python进程正在被创建,但当测试报告为通过时,它们并没有关闭。例如,如果运行两个测试,每个测试生成5个进程,那么系统监视器中将显示10个python进程 我尝试过使用terminate和join,但都没有成功。是否有办法强制测试在运行下一个测试之前正确关闭它生成的所

我正在尝试为使用多个进程的应用程序创建unittests,但在尝试同时运行所有测试时遇到了奇怪的问题。基本上,当单独运行测试时,它们会毫无问题地通过,但当按顺序运行时,例如运行文件中的所有测试时,某些测试将失败

我所看到的是,许多python进程正在被创建,但当测试报告为通过时,它们并没有关闭。例如,如果运行两个测试,每个测试生成5个进程,那么系统监视器中将显示10个python进程

我尝试过使用terminate和join,但都没有成功。是否有办法强制测试在运行下一个测试之前正确关闭它生成的所有进程

我正在Ubuntu 16.04中运行Python 2.7

编辑: 这是一个相当大的代码库,所以这里有一个简化的示例

从多处理导入管道,处理
基类设备:
#各种方法
通过
BaseInstr类(BaseDevice、Process):
def u u初始(自,管道):
进程。初始化(自)
self.pipe=管道
def运行(自):
#执行任务并等待管道上的终止消息
#各种其他更高级别的方法
类BaseComponuntInstrument(BaseInstr):
def u u初始(自,管道):
#创建多个工具,通常使用配置文件完成,但此处简化
BaseInstr.\uuuuuu初始\uuuuuuuuuuu(自,管道)
instrlist=list()
对于范围(5)内的uu:
主管道,辅助管道=管道()
instrlist.append([BaseInstr(slavepipe),masterpipe])
def运行(自):
通过
#监听来自管道的信息,将信息发送至子仪器
def关闭(自):
#收到停机信息后,发送至所有子仪表
通过
类测试(unittest.TestCase):
def设置(自):
#从示例配置加载配置文件,以便对其进行更新
self.parentConn,self.childConn=Pipe()
self.instr=BaseCompountInstrument(self.childConn)
self.instr.start()
def拆卸(自):
self.parentConn.send(“shutdown”)#传播到所有子仪器
def测试1(自我):
通过
def测试2(自我):
通过
经过一段时间(实际上是两天)的努力,我发现解决方案在技术上并没有错,但删除了所有可以使用的并行代码(仅在测试中,仅在测试中…)

我使用这个软件包来模拟函数(我现在意识到它是自Pytohn 3.3 xD以来unittest模块的一部分),您可以假设某个函数的执行工作正常修复某个返回值,或者更改函数本身

所以我做了最后一个选项:更改函数本身

在我的例子中,我使用了一个进程列表(因为在我的例子中不起作用),并在进程之间共享数据

我的原始代码如下所示:

import multiprocessing as mp


manager = mp.Manager()
list_data = manager.list()
list_return = manager.list()

def parallel_function(list_data, list_return)

    while len(list_data) > 0:
        # Do things and make sure to "pop" the data in list_data
        list_return.append(return_data)
    return None

# Create as many processes as images or cpus, the lesser number
processes = [mp.Process(target=parallel_function,
                        args=(list_data, list_return))
             for num_p in range(mp.cpu_count())]
for p in processes:
    p.start()
for p in processes:
    p.join(10)
因此,在我的测试中,我模拟了函数进程。从多处理模块开始执行并行函数,而不是创建一个新进程

在测试文件中,在进行任何测试之前,应定义尝试并行化的相同函数:

def fake_process(self, list_data, list_return):
    while len(list_data) > 0:
        # Do things and make sure to "pop" the data in list_data
        list_return.append(return_data)
    return None
在定义将要执行这部分代码的任何方法之前,您必须定义它的decorator来覆盖流程

@patch('multiprocessing.Process.__init__', new=fake_process)
@patch('multiprocessing.Process.start', new=lambda x: None)
@patch('multiprocessing.Process.join', new=lambda x, y: None)
def test_from_the_hell(self):
    # Do things
如果使用Manager数据结构,则不需要使用锁或任何东西来控制对数据的访问,因为这些结构是线程安全的


我希望这将有助于其他试图测试多处理代码的迷失灵魂。

共享您的代码将有助于找出错误所在。我用一个简化的示例对其进行了更新。对我来说,代码库相当大,可以提供更多的信息:(.我也有同样的问题:u(1年后,但是…你找到解决方案了吗?运行(至少)20个测试一个接一个不是comfortable@DanielRodríguez,我从来没有让它正常工作过,我的解决方案是不在整个系统上运行单元测试。相反,我将应用程序分解为更小、更容易测试的部分,并在以后对整个代码库进行更多的手动功能测试。这并不完美,但我这意味着写复杂模拟的时间减少了,至少对我来说是这样。希望这能有所帮助。哦,谢谢你的回复@Fratink。我在周五晚些时候找到了一个解决方案。对我来说是“更容易”因为我只有一段使用多处理的代码,所以我将把它作为未来人的答案发布!感谢发布该解决方案!我希望我们能够使用我们拥有的代码迁移到Python3,因为这样会使事情变得更简单。不幸的是,我已经换了工作,所以现在我不能再做得更好了:(.太棒了!