【问题标题】:Symfony phpunit test 'Killed'Symfony phpunit 测试“被杀死”
【发布时间】:2021-06-20 23:52:49
【问题描述】:

我使用 entityManager 获取我的存储库,但如果我尝试以任何方式访问它,似乎测试会开始无限循环,然后自行终止。如果我尝试在其中找到一个元素,或者只是打印整个变量测试就死了,这都没有关系。

public function testStuff()
    {
        $moduleRepository = $this->entityManager->getRepository(Module::class);
        fwrite(STDERR, print_r("asd", TRUE));

        //$result = $moduleRepository->find(1);
        fwrite(STDERR, print_r($moduleRepository, TRUE));
    }

输出:

PHPUnit 9.5.5 by Sebastian Bergmann and contributors.

Testing 
asdKilled

不访问变量:

public function testStuff()
    {
        $moduleRepository = $this->entityManager->getRepository(Module::class);
        fwrite(STDERR, print_r("asd", TRUE));

        //$result = $moduleRepository->find(1);
        //fwrite(STDERR, print_r($moduleRepository, TRUE));
    }

输出:

PHPUnit 9.5.5 by Sebastian Bergmann and contributors.

Testing 
asdmodule (App\Tests\module)
 ☢ Stuff

Time: 00:00.266, Memory: 22.00 MB


OK, but incomplete, skipped, or risky tests!
Tests: 1, Assertions: 0, Risky: 1.

我知道通过不调用变量 getRepository 甚至都没有启动,但是从第一次测试中您可以看到该方法没有任何错误完成,只有当您尝试访问它时才会出现问题。

【问题讨论】:

  • 什么是 $moduleRepository?如果你只是 var_dump() 那你会得到什么?
  • 它是一个数据库存储库,您不能在测试中使用 var_dump 输出
  • print_r() 可能有点古怪。尝试使用var_dump(),或者如果您需要更多花哨的东西,请使用VarDumper with its phpunit integration
  • @dbrumann 问题不在于打印出来,我无法对那个变量做任何事情,只要我以任何方式使用它,它就会终止我的测试。
  • 这很奇怪。您是编写自己的存储库还是使用 Doctrine 的默认存储库?您能否显示存储库的代码(仅具有构造函数的类结构)以及`bin/console debug:container ModuleRepository 的输出)?你是在代码中还是在测试中遇到了同样的问题?

标签: symfony phpunit


【解决方案1】:

这并不能具体回答您的问题,但对于未来的访问者来说,了解“已杀”部分可能很重要。

这是 Unix 错误消息“Killed”和other users are also seeing it in tests(这里也是与数据库相关的)。

这不是输出它的 Phpunit,而是内核杀死了运行 Phpunit 的 PHP 进程,很可能是 Out Of Memory Killer (OOM Killer),正如你可以想象的那样,Out of memory (OOM) 不是你想要的状态- 你的内核也没有。

和你描述的差不多:

似乎测试开始无限循环

并且可能会消耗越来越多的内存,直到内核终止进程。

然后在终端打印“Killed”消息。

当您在测试方法中找到该点时,$this->entityManager 很可能没有正确初始化/配置。

有时,清理代码出错也会发生这种情况,但这种可能性较小。更多时候是测试夹具的配置。

现在这可能无法为您提供确切的位置和解决方案,但希望有足够的指示。由于这类错误很难调试,因此可以帮助创建一个单独的新测试用例来仅测试此行为并使用尽可能少的测试代码重现它。

仅使用该测试用例运行测试套件,并且当它易于重现时,通过调试检查无限循环中的内容。通常它是一个特定的条件,例如缺少配置或初始化。

由于案例已经被隔离,因此隔离执行通常会带来更好更快的结果。如果您将来遇到类似的问题,您已经有一个测试用例来展示如何完成(或改进)它。

【讨论】:

  • 我在 11 年前发现了同样的问题。 user.phpunit.narkive.com/nWAarPD5/… 我仍然没有弄清楚为什么我可以使用 assert 访问变量,但不能以任何其他方式访问。这让测试变得非常困难,因为我只能在代码末尾看到变量的值,而在我的程序中间发现问题几乎是不可能的。
  • @belenka3000:当您遇到这种情况时,是否加载了 xdebug?当您遇到这种情况时,您是否正在使用模拟?备份全局变量?您是否能够在测试用例中隔离它并只执行该测试用例? var_dump() 可以进入无限递归。 xdebug 可能会在设置时阻止这种情况。像实体管理器这样的复杂系统可能有两种方式的引用(父 子),然后转储就像这样:父 -> 子 -> 父 -> 子 -> ...(永不停止)。然后 var_dump() 将消耗所有内存。所以可能不是配置,而是转储。
  • 模拟效果很好,我用另一个测试试过了。现在我正在从数据库中提取真实数据,这就是问题发生的时候。我对 phpunit 真的很陌生,我正在做一个非常大的项目,目前我在理解后端时遇到了比为它编写测试更多的问题,我认为这是一个与后端相关的问题,没有有人注意到它,因为没有人尝试过测试它。
  • 我会做的事情:尝试在不模拟的情况下进行复制。模拟也会产生副作用,它们可能是内存密集型/硬崩溃。
【解决方案2】:
$this->assertEquals(25,count($moduleRepository));

在我尝试断言我的结果之后,它奏效了。

【讨论】:

    猜你喜欢
    • 2011-07-27
    • 2015-04-26
    • 2019-11-22
    • 1970-01-01
    • 2015-01-14
    • 2011-10-30
    • 1970-01-01
    • 2018-06-27
    • 2018-11-05
    相关资源
    最近更新 更多