用于单元测试的临时对象池?

时间:2017-06-06 13:50:18

标签: python unit-testing memory-management garbage-collection virtualization

我正在为一个复杂的项目运行一个大型的单元测试库。 这个项目有一些不适合大量测试的东西:

  1. 缓存(memoization)导致对象不能在测试之间释放
  2. 模块级别的复杂对象,它们是单例,可能在使用时收集数据
  3. 我对每个测试(或至少每个测试套件)都有自己的" python-object-pool"并且能够在之后释放它。

    排序python-garbage-collector-problem变通方法。

    我想象一个python自包含的临时和可丢弃的解释器,可以为我运行某些代码,之后我可以调用" interpreter.free()"并且放心它不会泄漏。

    我找到的一个棘手的解决方案是使用Nose或者通过子进程实现这一点,每次我需要一个可以运行测试的可消耗解释器。所以每个测试变成" fork_and_run(条件)"并且在原始过程中没有泄漏任何记忆。

    每次测试都会看到Nose单个进程,然后进行基本的测试 - 尽管有人提到它有时会中途冻结 - 不那么有趣..

    是否有更简单的解决方案?

    P.S。 我对通过大量其他人的代码并尝试使所有缓存/对象/项目成为可以清理的完美内存管理对象不感兴趣。

    P.P.S 我们的PROD代码也为每个工作创建了一个新的流程,这非常舒适,因为我们不必喋喋不休地永久地生存下来"和其他可怕的故事。

1 个答案:

答案 0 :(得分:0)

TL; DR 模块重载技巧我尝试在本地工作,在使用不同python版本的机器上时断开...(?!)

我最终获取了我在代码中编写的任何和所有缓存,并将它们添加到全局缓存列表中 - 然后在测试之间清除它们。 遗憾的是,如果有人使用缓存/手动缓存机制并且忽略了这一点,这将会中断,测试将再次开始在内存中增长......

对于初学者,我写了一个循环,遍历sys.modules dict并重新加载(循环两次)我的代码的所有模块。这非常有效 - 所有引用都被正确释放,但它似乎不能用于生产/严重代码中,原因有多种:

  1. 旧的python版本在重新加载时会中断,并且重新定义了继承元类的类(我仍然不知道它是如何破坏的。)
  2. 单元测试在重新加载后仍然存在,并且有时对旧类具有错误实例 - 特别是如果类使用另一个类实例。想想super(class_name,self),其中self是先前定义的类,现在class_name是redefined-same-name-class。