Python 3.x Pytest unittest函数没有';不返回任何值
你们能帮我理解下面单元测试的问题吗? 下面是我正在编写的unittest函数Python 3.x Pytest unittest函数没有';不返回任何值,python-3.x,pytest,Python 3.x,Pytest,你们能帮我理解下面单元测试的问题吗? 下面是我正在编写的unittest函数 def从_数据库(设备)运行_config_: 尝试: 数据=数据库代理(群集服务器)https://xxx.xxxx.xxx.net') datadb='test' query=f'''fGetrunningconfigData('{device}') ''' 原始数据=数据。执行查询(datadb,查询) #pdb.set_trace() 对于原始数据中的项。fetchall() config=items['con
def从_数据库(设备)运行_config_:
尝试:
数据=数据库代理(群集服务器)https://xxx.xxxx.xxx.net')
datadb='test'
query=f'''fGetrunningconfigData('{device}')
'''
原始数据=数据。执行查询(datadb,查询)
#pdb.set_trace()
对于原始数据中的项。fetchall()
config=items['config'].split('\r\n')
对于索引,枚举(配置)中的行:
如果行中有“$PASS$”:
如果line.startswith('set groups ospf_test'):
config_line=line.replace(“$PASS$”,get_auth('ospf'))
配置[索引]=配置行
elif line.startswith('set groups rip_test'):
config_line=line.replace(“$PASS$”,get_auth('rsvp'))
配置[索引]=配置行
配置=配置+重载配置
返回True,'\r\n'。加入(配置)
例外情况除外,如e:
返回False,f'未能从数据库中获取正在运行的配置,错误:{e}'
下面是我对该函数的单元测试:
@patch("scripts.test.overload_config")
@patch("scripts.test.get_auth")
@patch("scripts.test.databaseproxy.execute_query")
def test_running_config_from_database(self, mock_data, mock_cred, mock_overload):
ret = MagicMock()
ret.fetchall.return_value = [{'Hostname': 'devA', 'Config': 'set groups ospf_test secret $PASS$\r\n'}]
mock_data.return_value = ret
mock_cred.return_value = 'xyz'
mock_overload = ['sample_overload_config1', 'sample_overload_config2']
expected = ['set groups ospf_test secret xyz', '']
out = expected + mock_overload
data = '\r\n'.join(out)
status, out1 = tests.test_scripts.running_config_from_database('devA')
assert status and out1 == data
当我运行这个unittest来测试函数时,我得到了下面的断言错误——看起来函数没有返回任何值
@patch("scripts.test.overload_config")
@patch("scripts.test.get_auth")
@patch("scripts.test.databaseproxy.execute_query")
def test_running_config_from_database(self, mock_data, mock_cred, mock_overload):
ret = MagicMock()
ret.fetchall.return_value = [{'Hostname': 'devA', 'Config': 'set groups ospf_test secret $PASS$\r\n'}]
mock_data.return_value = ret
mock_cred.return_value = 'xyz'
mock_overload = ['sample_overload_config1', 'sample_overload_config2']
expected = ['set groups ospf_test secret xyz', '']
out = expected + mock_overload
data = '\r\n'.join(out)
status, out1 = tests.test_scripts.running_config_from_database('devA')
> assert status and out1 == data
E AssertionError: assert (True and '' == 'set groups d...rload_config2'
E + set groups ospf_test secret xyz
E +
E + sample_overload_config1
E + sample_overload_config2)
tests/test_scripts.py:80: AssertionError
我编辑了我的函数以降低复杂性,但它仍然不起作用。不知道为什么
Main Function:
==============
def running_config_from_database(device):
try:
pdb.set_trace()
config = running_config_database(device)
for index, line in enumerate(config):
if '$PASS$' in line:
if line.startswith('set groups ospf_test'):
config_line = line.replace('$PASS$', get_cred('ospf'))
config[index] = config_line
config = config + overload_config
return True, '\r\n'.join(config)
except Exception as e:
return False, f'Failed to get the running config from Database, error: {e}'
上述功能的单元测试结果:
=========================================================================================================== FAILURES ============================================================================================================
________________________________________________________________________________________________ test_running_config_from_database _________________________________________________________________________________________________
mock_cred = <MagicMock name='get_cred' id='140210277622336'>, mock_overload = ['sample_overload_config1', 'sample_overload_config2'], mock_running_config = <MagicMock name='running_config_database' id='140210277652128'>
@patch("test.test1.scripts.running_config_database")
@patch("test.test1.scripts.overload_config")
@patch("test.test1.scripts.get_cred")
def test_running_config_from_database(mock_cred, mock_overload, mock_running_config):
mock_running_config.return_value = ['set groups ospf_test secret $PASS$', '']
mock_cred.return_value = 'xyz'
mock_overload = ['sample_overload_config1', 'sample_overload_config2']
expected = ['set groups ospf_test secret xyz', '']
out = expected + mock_overload
data = '\r\n'.join(out)
status, out1 = test.test1.scripts.test_running_config_from_database('devA')
> assert status and out1 == data
E AssertionError: assert (True and '' == 'set groups d...rload_config2'
E + set groups ospf_test secret xyz
E +
E + sample_overload_config1
E + sample_overload_config2)
validation_tests/test_scripts.py:152: AssertionError
================================================================================================== 1 failed, 6 passed in 4.79s ==================================================================================================
============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
________________________________________________________________________________________________测试\u从\u数据库运行\u config\u_________________________________________________________________________________________________
mock\u cred=,mock\u重载=['sample\u重载\u config1','sample\u重载\u config2',mock\u running\u config=
@补丁(“test.test1.scripts.running\u config\u database”)
@补丁(“test.test1.scripts.overload\u config”)
@补丁(“test.test1.scripts.get_cred”)
def test_running_config_来自_数据库(mock_cred、mock_重载、mock_running_config):
mock_running_config.return_value=[“设置组ospf_测试机密$PASS$”,“”]
模拟信任返回值='xyz'
模拟过载=['sample\u过载\u配置1','sample\u过载\u配置2']
预期=['set groups ospf_test secret xyz','']
输出=预期+模拟负载
数据='\r\n'。加入(输出)
状态,out1=test.test1.scripts.test\u从数据库('devA')运行配置
>断言状态和out1==数据
E AssertionError:assert(True和“”='设置组d…rload_config2'
E+集组ospf_测试秘密xyz
E+
E+样本\u过载\u配置1
E+样本\过载\配置2)
验证测试/测试脚本。py:152:AssertionError
====================================================================================================================================================================================================================================1次失败,6次在4.79秒内通过==================================================================================================
答案已由@MrBean breme在评论部分提供。下面是建议进行更改后的UT
@patch("scripts.test.overload_config")
@patch("scripts.test.get_auth")
@patch("scripts.test.databaseproxy.execute_query")
def test_running_config_from_database(self, mock_data, mock_cred, mock_overload):
ret = MagicMock()
ret.fetchall.return_value = [{'Hostname': 'devA', 'Config': 'set groups ospf_test secret $PASS$\r\n'}]
mock_data.return_value = ret
mock_cred.return_value = 'xyz'
***mock_overload[:]*** = ['sample_overload_config1', 'sample_overload_config2']
expected = ['set groups ospf_test secret xyz', '']
out = expected + mock_overload
data = '\r\n'.join(out)
status, out1 = tests.test_scripts.running_config_from_database('devA')
assert status and out1 == data
这里的问题是对
mock\u重载的赋值。如果要调整模拟对象,必须确保对象本身已更改。如果您只分配了另一个对象(在本例中为列表),那么您的变量现在将指向列表对象,而原始的mock_重载
将不再被引用(并且不会更改)。因此,与其写:
mock_-overload=['sample_-overload_-config1','sample_-overload_-config2']
例如,你可以写
mock\u-overload[:]=['sample\u-overload\u-config1','sample\u-overload\u-config2']
为了澄清,以下是原始代码的简化版本:
>>> mock_overload = []
>>> id(mock_overload)
1477793866440
>>> mock_overload = [5, 6]
>>> id(mock_overload)
1477791015560 <- changed id, no longer pointing to the mock
您模拟“scripts.test.xxx”
,但调用tests.test\u scripts。从\u数据库运行\u config\u
。你不应该也模拟测试。测试脚本.xxx
?另外,你只需重新分配模拟重载
,因此模拟不被使用-如果它是一个列表,你可能应该改为执行模拟重载[:]=[…]
。除此之外,在我看来还可以。您是否注意到编写此测试的复杂性随着功能的增加而增加?也许是时候考虑把你的函数分解成更小的部分了,这样函数就可以做一件事,让测试更容易…@beanbremen先生,谢谢你的评论。在粘贴输出之前,我必须编辑函数/单元测试,这就是您看到差异的原因。我嘲笑了所有的依赖关系。@gold_cy,是的,我正在努力,但我想知道,我做错了什么
>>> mock_overload = []
>>> id(mock_overload)
140732764763024
>>> mock_overload[:] = [5, 6]
>>> id(mock_overload)
140732764763024 <- unchanged id, still points to the mock