如何在python中模拟/单元测试以下代码?

2024-04-28 07:00:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我将如何对以下内容进行单元测试?你知道吗

def sigterm_handler(signum, frame):
    pid = os.getpid()  # type: int
    sys.exit(0)

signal.signal(signal.SIGTERM, sigterm_handler)

我应该嘲笑并确保调用mock吗?你知道吗


Tags: signalosdeftypesysexit单元测试pid
3条回答

猴子修补处理程序并在测试时发送信号?你知道吗

import os
import signal
import sys
import time

# your handler
def sigterm_handler(signum, frame):
    print("Handled")
    pid = os.getpid()  # type: int  FIXME: what's this for?
    sys.exit(0)

signal.signal(signal.SIGTERM, sigterm_handler)

# Mock out the existing sigterm_handler
_handled = False
def mocked_sigterm_handler(signum, frame):
    print("Mocked")
    _handled = True

# register the handler
signal.signal(signal.SIGTERM, mocked_sigterm_handler)

# test sending the signal
os.kill(os.getpid(), signal.SIGTERM)
print(f"done ({_handled})")

# reset your handler?
signal.signal(signal.SIGTERM, sigterm_handler)

如果你想测试你的处理程序本身,你可能需要放一些这样的代码。。在一个不漂亮的地方。你知道吗

if _unittesting_sigterm_handler:
    _handled = True
else:
    sys.exit(0)

然后您可以直接调用处理程序(或者在调用中传递test标志)。你知道吗

_unittesting_sigterm_handler = True
sigterm_handler(0, None)

我将编写一个测试,在子进程中运行您的代码,该子进程可以检查您是否成功终止。你知道吗

例如,假设您的问题代码位于名为signals.py的模块中。您可以编写如下所示的测试包装器模块:

测试信号_包装器.py

from time import sleep
from sys import exit

# import this last to ensure it overrides any prior settings
import signals

while True:
    sleep(1)

exit(1)  # just in case the loop ends for other reasons

现在您可以编写如下所示的单元测试:

测试_信号.py

from subprocess import run, TimeoutExpired
from sys import executable

def test_sigterm_handler():
    try:
        status = run([executable, '-m', 'test_signals_wrapper'], timeout=30)
    except TimeoutExpired:
        assert False, 'Did not trigger assertion in 30 seconds'

    assert status.returncode == 0, f'Wrong return code: {status.returncode}'

这需要一点额外的基础设施来进行测试,但它解决了测试此代码的所有问题。通过在子进程中运行,您可以自由地执行sys.exit并获取返回值。通过使用包装器脚本,可以控制代码的加载和运行方式。您不需要模拟任何东西,只要确保包设置正确,并且测试运行程序不会尝试将包装器脚本作为测试。你知道吗

您显示的代码行不适合进行单元测试,而应该进行集成测试。原因是,您的代码行只包含与其他组件(在本例中是signalsysos模块)的交互。你知道吗

因此,您可能会遇到的bug存在于与这些其他组件的交互中:您是否以正确的顺序调用了正确组件中的正确函数以及参数的正确值,结果/反应是否与您预期的一样?你知道吗

所有这些问题都无法在单元测试中得到回答,在单元测试中,应该会发现可以在独立单元中找到的bug:如果您模拟signalsys和/或os依赖项,那么您将编写模拟,以便它们反映您对这些组件的(可能是错误的)理解。因此,单元测试将成功,尽管集成系统中的代码可能会失败。如果您的目的是让代码在不同的系统上工作,那么您甚至可能会遇到这样的情况:代码在一个集成(可能是Linux)中工作,但在另一个集成(可能是Windows)中失败。你知道吗

因此,对于像您这样的代码,单元测试和模拟单元测试没有太大的价值。你知道吗

相关问题 更多 >