Python 在不同单元测试中重用生成器

Python 在不同单元测试中重用生成器,python,unit-testing,Python,Unit Testing,我在对一个使用生成器的Python项目进行单元测试时遇到了一个问题。简化后,项目/单元测试如下所示: 我有一个setUp()函数,用于创建Person实例。Person是一个具有生成器next_task()的类,它生成Person拥有的下一个任务 我现在有两个单元测试,使用for循环测试生成器工作方式的不同方面。第一个测试完全按照我的预期工作,第二个测试甚至从未进入循环。在两个单元测试中,第一行代码是: for rank, task in enumerate(self.person.next_t

我在对一个使用生成器的Python项目进行单元测试时遇到了一个问题。简化后,项目/单元测试如下所示:

我有一个setUp()函数,用于创建Person实例。Person是一个具有生成器next_task()的类,它生成Person拥有的下一个任务

我现在有两个单元测试,使用for循环测试生成器工作方式的不同方面。第一个测试完全按照我的预期工作,第二个测试甚至从未进入循环。在两个单元测试中,第一行代码是:

for rank, task in enumerate(self.person.next_task()):

我猜这不起作用,因为在两个单独的单元测试中使用了相同的生成器函数。但这看起来不像是生成器或单元测试应该工作的方式。难道我不能在任务列表中重复两次吗?另外,每个单元测试是否应该使用本质上不同的Person实例,因为Person实例是在setUp()中创建的?

生成器的生成结果被使用它的第一个
for
循环消耗。之后,生成器函数返回并完成-因此为空。由于第二个单元测试使用的是同一个生成器对象,因此它不会进入循环。您必须为第二个单元测试创建一个新的生成器,或者使用从一个生成器中生成N个独立的迭代器

发电机不能按你想象的方式工作。每次调用
generatorObject.next()
,都会返回下一个生成的结果,但结果不会存储在任何地方。这就是为什么生成器经常用于延迟操作。如果您想重用结果,可以像我说的那样使用
itertools.tee
,或者将生成器转换为结果的元组/列表

关于使用文档中的
itertools.tee
的提示:

此itertool可能需要大量辅助存储(取决于需要存储的临时数据量)。通常,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,那么使用list()而不是tee()会更快


如果您真的要在设置中创建一个新的Person对象,那么它应该按照您的预期工作。它可能不起作用的原因有几个:

1) 您正在从另一个迭代器初始化人员的任务,在您第二次创建人员时,该任务已被耗尽

2) 您每次都在创建一个新的Person对象,但任务生成器是一个类变量而不是实例变量,因此在类实例之间共享

3) 您认为您正在创建一个新的Person对象,但实际上您并非出于某种原因。也许它是作为单例实现的

4) unittest设置方法已损坏


我认为(4)是最不可能的,但我们需要看到更多的代码,然后才能找到真正的问题。

如果您自己运行第二个测试,它能工作吗?e、 g.如果您在命令行中指定它。使用
python testfile.py TestClass.testMethod
;It’迭代器的工作方式是:值不存储在列表中。一旦遍历了迭代器一次,就不能返回到开始并再次执行。听起来两个测试都在测试同一个
Person
;您可以通过让他们打印
id(self.person)
来检查这一点。
person.next\u task()
方法是什么样的?
setUp()
方法怎么样?根据您的描述,听起来这两个测试应该使用两个独立的
Person
实例,因为您正在
setUp()
中创建它们。谢谢-实际上类似于#2。生成器实际上引用了一个类变量(一组),我忘记了在每个单元测试结束时清除类变量。