我遇到了一个有趣的问题。我正在使用PHPUnit,我的测试每次运行时都会占用更多内存。即...
2.25 MB
2.5 MB
3.0 MB
3.5 MB .......
有谁知道如何清除正在消耗的内存,任何人都可以建议我深入探讨这个问题吗?当前的问题是我的一些较大的测试耗尽了内存,并且只是继续增加PHP中的最大内存分配还不够......我需要知道为什么从命令行运行的PHPUnit测试会有内存在跑步之间“徘徊”的用法。
答案 0 :(得分:24)
内存增加有三到四个原因:
除了关闭代码覆盖率外,你无能为力。
您可以在PHPUnit xml中使用<phpunit cacheTokens="false">
。请参阅http://phpunit.de/manual/current/en/installation.html#installing.upgrading
在其当前实现中,它保留了测试用例,因为存储结果数据的位置。在未来,这将变得更加有效,但现在它是如何运作的。
由于保留了TestCase
个实例,因此您的成员变量也会被保留。
意味着您可以使用
节省大量内存public function tearDown() {
unset($this->whatever);
}
但这样做非常乏味。
我的建议是为所有TestCase设置一个基础测试类并使用它:
class MyBaseTest extends \PHPUnit_Framework_TestCase {
protected function tearDown()
{
$refl = new \ReflectionObject($this);
foreach ($refl->getProperties() as $prop) {
if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
$prop->setAccessible(true);
$prop->setValue($this, null);
}
}
}
}
这将以一种不错的自动方式清理完毕。
(该片段的道具转到:http://kriswallsmith.net/post/18029585104/faster-phpunit)
PHPUnit不能以向后兼容的方式执行此操作,不会破坏人们的项目,因此您必须为自己添加它:)
答案 1 :(得分:5)
Calvin,正如chat中讨论的那样,这是由于缺少重置功能。
测试时,我们必须确保测试环境一致,以便我们能够获得准确的结果。计算是输入/输出,因此我们应该使用Fixtures in PHPUnit重置存储以防止像这样的“内存泄漏”。
答案 2 :(得分:4)
@Unorian和@mauris已经涵盖了PHPUnit垃圾收集背后的技术细节,但是我想补充一点,PHPUnit(至少在我正在运行的3.7.21版本中)让你能够添加评价:
/**
* @backupGlobals disabled
*/
class MyClassTests extends PHPUnit_Framework_TestCase{}
在添加注释之前,我的每次运行测试套件的内存使用量大致翻了一倍,最后一次测试大约1100 MB。现在他们的运行速度为15 MB。
答案 3 :(得分:1)
如果您正在使用PDO(或类似的数据库抽象),那么您可以使用“sqlite :: memory:”作为DSN。这有三大优势:
缺点是您的SQL必须可以在MySQL和SQLite之间移植。这可能是相当多的工作(对于更大的项目,它通常是值得的,不仅仅是测试,而是它将改进代码设计的方式。)在你的情况下,你提到使用Doctrine,在聊天记录中,所以你可能已经有了很好的抽象,因此它可能只是在SQLite上没有变化的情况下运行。