Python 3.x Pytest Cov报告缺少模拟异常返回
我是一名网络工程师,正在尝试编写一些Python,因此每天都在学习。我对单元测试和Pytest覆盖率报告有意见。我想我理解单元测试和pytest的概念 我有一个使用套接字进行DNS查找的函数Python 3.x Pytest Cov报告缺少模拟异常返回,python-3.x,unit-testing,pytest,pytest-mock,pytest-cov,Python 3.x,Unit Testing,Pytest,Pytest Mock,Pytest Cov,我是一名网络工程师,正在尝试编写一些Python,因此每天都在学习。我对单元测试和Pytest覆盖率报告有意见。我想我理解单元测试和pytest的概念 我有一个使用套接字进行DNS查找的函数 def get_ip(d): """Returns the first IPv4 address that resolves from 'd' Args: d (string): string that needs to be resolved
def get_ip(d):
"""Returns the first IPv4 address that resolves from 'd'
Args:
d (string): string that needs to be resolved in DNS.
Returns:
string: IPv4 address if found
"""
logger.info("Returns IP address from hostname: " + d)
try:
data = socket.gethostbyname(d)
ip_addr = repr(data).strip("'")
logger.debug("IP Address Resolved to: " + ip_addr)
return ip_addr
except socket.gaierror:
return False
我已经写了一个单元测试,通过得很好。我正在使用pytestmock来处理DNS查找套接字的模拟。副作用似乎是模仿异常,我将return_值设置为False,我假设我已经断言返回False,测试通过了ok,这就是为什么我假设我的测试是ok
import pytest
import pytest_mock
import socket
from utils import network_utils
@pytest.fixture
def test_setup_network_utils():
return network_utils
def test_get_ip__unhappy(mocker, test_setup_network_utils):
mocker.patch.object(network_utils, 'socket')
test_setup_network_utils.socket.gethostbyname.side_effect = socket.gaierror
with pytest.raises(Exception):
d = 'xxxxxx'
test_setup_network_utils.socket.gethostbyname.return_value = False
test_setup_network_utils.get_ip(d)
assert not test_setup_network_utils.socket.gethostbyname.return_value
test_setup_network_utils.socket.gethostbyname.assert_called_once()
test_setup_network_utils.socket.gethostbyname.assert_called_with(d)
pytest cov报告显示返回错误行未被覆盖
pytest --cov-report term-missing:skip-covered --cov=utils unit_tests
network_utils.py 126 7 94% 69
第69行是函数中代码的下一行
except socket.gaierror:
return False <<<<<<<< This is missing from the report
除了socket.gai错误:
声明时返回False
mocker.patch.object(network_utils, 'socket')
您将用单个模拟替换整个套接字
模块,因此套接字
模块中的所有内容也将成为模拟,包括套接字.gaierror
。因此,当试图在运行测试时捕获socket.gaierro
时,Python会抱怨它不是异常(不从BaseException
中生成子类),并失败。因此,不执行所需的返回行
总的来说,您的测试看起来过于工程化,并且包含大量不必要的代码。您需要什么测试设置\u网络\u实用工具
?为什么在测试中捕获任意异常?重新访问的test\u get\u ip\u unful
,涵盖了GAIRROR
案例中的完整代码:
def test_get_ip__unhappy(mocker):
# test setup: patch socket.gethostbyname so it always raises
mocker.patch('spam.socket.gethostbyname')
spam.socket.gethostbyname.side_effect = socket.gaierror
# run test
d = 'xxxxxx'
result = spam.get_ip(d)
# perform checks
assert result is False
spam.socket.gethostbyname.assert_called_once()
spam.socket.gethostbyname.assert_called_with(d)
当然,spam
只是一个例子;将其替换为您的实际导入。谢谢您的回复,您用模拟解释的内容是有意义的。在代码中,我在测试中使用test\u setup\u network\u utils fixture参数来删除VScode抛出的错误,这可能不合理,但我每天都在学习。你建议的代码工作得很好,我有一个干净的测试,所有的行都被覆盖了。再次感谢。