Python 如何为访问从csv文件创建的全局字典的函数编写单元测试?
我有一个process_persons()Python函数,它访问全局字典,如下所示:Python 如何为访问从csv文件创建的全局字典的函数编写单元测试?,python,unit-testing,global-variables,Python,Unit Testing,Global Variables,我有一个process_persons()Python函数,它访问全局字典,如下所示: def process_persons(): for k, v in person_dict.items(): # do some processing def main(): global person_dict person_dict = {} reader = csv.reader(open('person_file.csv', 'r'
def process_persons():
for k, v in person_dict.items():
# do some processing
def main():
global person_dict
person_dict = {}
reader = csv.reader(open('person_file.csv', 'r'))
for row in reader:
key = (row[0], row[1])
person_dict[key] = row[2]
我编写了如下的单元测试:
def test_process_persons(self):
process_persons()
# assert that the processing is done right!
但是我得到了一个错误:NameError:没有定义全局名称“person\u dict”。感谢您的帮助
请注意,我无法更改正在测试的方法的签名 我认为它实际上是没有定义的。请尝试用以下内容替换
global person\u dict
:
person_dict = {}
name错误:未定义全局名称“person\u dict”
那是因为你没有定义它。它怎么知道它是什么?你说person\u dict[key]=row[2]
,但这并不自动使它成为字典。您必须用一个值初始化它,例如
person_dict = {}
上面说这是一本空字典
也不需要
全局
声明。您正在将其作为文件的顶层执行(即,不在函数或类中),以便可以正常使用。不确切地确定您要实现的目标,但考虑到被测函数的签名已冻结,我可能会这样做
def process_persons():
for k, v in person_dict.items():
# do some processing
person_dict = {}
if __name__ == '__main__':
reader = csv.reader(open('person_file.csv', 'r'))
for row in reader:
key = (row[0], row[1])
person_dict[key] = row[2]
你需要在某个地方定义一个人。声明它是全局的并不能定义它<代码>全局用于指定在模块级从函数中定义的变量。如果未指定global
,则将在函数中创建一个新的局部变量,该变量将隐藏全局变量。然后,当函数退出时,您新创建的变量将超出作用域,被垃圾收集,并被遗忘为无用
现在您已经在模块级别定义了person dict,您只需在调用
process\u persons
更改输入数据之前从测试代码中为其分配即可。对我的代码进行了一些更改。用def main()
替换if uuuuu name\uuuuuuuu==''uuuuuuu main\uuuuuuuuu:
,并添加person\u dict={}
@Malgidef main
很好,但把person\u dict={}
放在外面,就像托拜厄斯做的那样。放下global
东西,你不需要它,这通常是不好的做法。Tobias的解决方案不起作用,因为当我们在单元测试test\u process\u persons()内部调用test\u process\u persons()
时,person\u dict
是空的,CSV文件还没有存储在itAh中,我明白你在说什么了。那么,您是在测试中调用main()
?在这种情况下,它可能不应该被称为main
,而是initialise\u person\u dict
或其他什么。或者根本不把它放在函数中,但如果uuu name uuu=='\uuuu main uuu'
也不要放在下,因为这只会在直接运行模块时起作用。实际上,我实际的main()
并没有那么简单。它有一些输入参数,用于指定person\u文件的路径。因此,如果我把它放在函数中或从测试中调用“main()”,我应该知道这些参数并将它们传递给该函数或main()
。我想除了删除全局字典person\u dict
,并将process\u persons()
更改为'process\u persons(person\u dict)':/对我的代码进行了一些更改之外,没有其他方法了。用def main():
替换了if uuuuuuu name\uuuuuuuuu==''uuuuuuuu main:
,并添加了person\u dict={}
。感谢您的回答。我对代码做了一些更改。如果使用def main():
替换\uuu name\uuuuuuu==''uuuuuuu main\uuuuuu':
,并添加了person\u dict={}
。您现在怎么想?您的解决方案不起作用,因为当我们在单元测试中调用process\u persons()
时test\u process\u persons()
的person\u dict
是空的,CSV文件还没有存储在其中。我想这一切都取决于您想要测试什么。是流程中的功能
,还是main中的功能
,还是两者兼而有之?要查看新的main
函数从process\u persons
读取的数据,您必须将person\u dict
的声明移动到模块级别。否则它将无法从流程人员访问。现在,通过测试,您可以首先调用main
,然后调用process\u persons
。