Python unittest 框架,不幸的是没有内置超时可能性

问题描述

我正在使用 python unittest 框架来执行单元测试。我使用的 python 版本是 3.6。我使用的是 Windows 操作系统。

我的生产代码目前有点不稳定(因为我添加了一些新功能)并且倾向于在一些内部异步循环中挂断。目前,我正在努力解决这些问题。 然而,相应的测试用例挂起也阻碍了对这些错误的跟踪。 我只是希望相应的测试用例在例如之后停止如果它们没有通过并被标记Failed 以让所有其他测试用例继续进行,则为 500 毫秒。

不幸的是,unittest 框架不支持超时(如果我事先知道......)。因此,我正在寻找解决方法。如果某个包会将缺少的功能添加到 unittest 框架中,我愿意尝试。我不想要的是我的生产代码依赖太多的非标准包,对于单元测试来说这没问题。

我对如何向单元测试添加这样的功能有点迷茫。 因此,我只是从这里尝试了一些代码How to limit execution time of a function call?。正如他们在某处所说的 threading 不应该用于实现超时,我也尝试使用 multiprocessing。 请注意,此处提出的解决方How to specify test timeout for python unittest? 也不起作用。它们是为 linux 设计的(使用 SIgalRM)。

import multiprocessing
# import threading
import time
import unittest

class InterruptableProcess(multiprocessing.Process):
# class InterruptableThread(threading.Thread):
    def __init__(self,func,*args,**kwargs):
        super().__init__()
        self._func = func
        self._args = args
        self._kwargs = kwargs
        self._result = None

    def run(self):
        self._result = self._func(*self._args,**self._kwargs)

    @property
    def result(self):
        return self._result


class timeout:
    def __init__(self,sec):
        self._sec = sec

    def __call__(self,f):
        def wrapped_f(*args,**kwargs):
            it = InterruptableProcess(f,**kwargs)
            # it = InterruptableThread(f,**kwargs)
            it.start()
            it.join(self._sec)
            if not it.is_alive():
                return it.result
            #it.terminate()
            raise TimeoutError('execution expired')
        return wrapped_f


class MyTests(unittest.TestCase):
    def setUp(self):
        # some initialization
        pass

    def tearDown(self):
        # some cleanup
        pass

    @timeout(0.5)
    def test_XYZ(self):
        # looong running
        self.assertEqual(...)

使用线程和进程时,代码的行为非常不同。 在第一种情况下,尽管超时(这是不需要的),它会运行但继续执行该函数。在第二种情况下,它抱怨无法拾取的对象

在这两种情况下,我都想知道如何进行适当的清理,例如超时时从装饰器类中调用 unittest.TestCase.tearDown 方法

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...