FilterIterator 应该是 PHPUnit\Framework\TestSuiteIterator 的实例

Posted

技术标签:

【中文标题】FilterIterator 应该是 PHPUnit\\Framework\\TestSuiteIterator 的实例【英文标题】:FilterIterator should be instance of PHPUnit\Framework\TestSuiteIteratorFilterIterator 应该是 PHPUnit\Framework\TestSuiteIterator 的实例 【发布时间】:2021-09-24 05:49:43 【问题描述】:

当我激活 Xdebug 并运行 phpUnit 单元测试时,会出现此错误:❌

Warning: assert(): assert($iterator instanceof FilterIterator) failed in [...]/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php on line 57
[... some stack trace information ...]
Return value of PHPUnit\Runner\Filter\Factory::factory() must be an instance of FilterIterator, instance of PHPUnit\Framework\TestSuiteIterator returned

我正在使用

PHPUnit 9.5.6 by Sebastian Bergmann and contributors.
Runtime: PHP 7.4.21 with Xdebug 2.8.0

PHPUnit 执行调用(与 PhpStorm 一起包含)如下所示:

/usr/bin/php74.bin.cli 
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so 
-dxdebug.collect_params=5 
-dxdebug.profiler_enable=on 
-dxdebug.auto_trace=1 -dxdebug.trace_format=1 
-dxdebug.collect_return=1 -ddisplay_errors=1 
-ddisplay_startup_errors=1 -derror_reporting=E_ALL 
-dmemory_limit=512M 
[...]/vendor/phpunit/phpunit/phpunit 
--coverage-filter [...]/src/ 
--bootstrap [...]/utils/unittest/bootstrap.php 
--configuration [...]/utils/unittest/phpunit.xml 
--filter "/(BasicsTest::testReturnBytes)( .*)?$/" 
--test-suffix BasicsTest.php [...]/utils/unittest/basics --teamcity

在激活 Xdebug 的情况下调用一个简单的 php 脚本效果很好。 ✔️

/usr/bin/php74.bin.cli 
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so 
-dxdebug.collect_params=5 
-dxdebug.profiler_enable=on -dxdebug.auto_trace=1 
-dxdebug.trace_format=1 -dxdebug.collect_return=1 
-ddisplay_errors=1 -ddisplay_startup_errors=1 
-derror_reporting=E_ALL -dmemory_limit=512M ./test.php

在没有激活 Xdebug 的情况下调用单元测试效果很好。 ✔️

/usr/bin/php74.bin.cli 
-dallow_url_fopen=1 
[...]/vendor/phpunit/phpunit/phpunit 
--no-coverage 
--bootstrap [...]/utils/unittest/bootstrap.php 
--configuration [...]/utils/unittest/phpunit.xml 
--filter "/(BasicsTest::testReturnBytes)( .*)?$/" 
--test-suffix BasicsTest.php [...]/utils/unittest/basics --teamcity

我的 phpunit.xml

<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
         bootstrap="bootstrap.php"
         colors="true"
         verbose="true">
  <coverage>
    <include>
      <directory suffix=".php">../../../src/*</directory>
      <directory suffix=".php">../../../some other dirs/*</directory>
    </include>
    <exclude>
        <directory suffix=".php">../../../some other dirs/*</directory>
    </exclude>
    <report>
        <html outputDirectory="./x_testresults" lowUpperBound="35" highLowerBound="70"/>
    </report>
  </coverage>
  <php>
    <ini name="allow_url_fopen" value="On"/>
    <ini name="memory_limit" value="5G"/>
    <ini name="include_path" value="."/>
  </php>
</phpunit>

单元测试

<?php
declare(strict_types = 1);

class BasicsTest extends PHPUnit\Framework\TestCase

    function testReturnBytes(): void 
        $this->assertSame(1, 1);
    

文档在https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#including-files 中说

必须配置一个过滤器来告诉 PHPUnit 哪些源代码文件包含在代码覆盖率报告中。这可以使用 --coverage-filter 命令行选项或通过配置文件来完成(参见元素)。

这就是我所做的,见上文。同样没有设置--coverage-filter参数PHPUnit抱怨缺少过滤器信息,所以我添加了它。

对我来说,感觉问题与--coverage-filter 参数有关。错误消息(见第一段代码)说 FilterIterator 应该是 PHPUnit\Framework\TestSuiteIterator 的实例,但我不知道在哪里调整它。

【问题讨论】:

这看起来令人费解。乍一看,我可能会重新初始化 phpunit(将您的配置移开并让 phpunit init 创建一个新配置),只是为了快速测试。然后我会再次交换配置文件并使用 xdebug 3 运行。 您在 XML 中真的有 * 吗?看起来它打破了 SO 上突出显示的语法,但我也认为它不需要。 @hakre 我确实已经使用了不同的配置,没有积极的结果。 * 在那里。没有它会尝试。 @hakre 没有 XML 中的 * 没有变化。 您能否再次检查 xdebug 2(即 EOL)仍然支持代码覆盖并与 phpunit 9.5 完全兼容?并不是说最后只是不兼容。 【参考方案1】:

我在我的设置中发现了一些错误,我找到了一种解决方法来让测试与 Xdebug 一起运行。

错误:

phpunit.xml 中包含和排除标签的相对路径错误 命令行命令上的 xdebug 设置“-dxdebug.auto_trace=1”已过时,see docs。实际上很奇怪 test.php 运行良好。

解决方法:

将测试套件设置为“.”在 phpunit.xml 中并通过 --testsuite default 调用它 为我要测试的特定类设置一个“@group dummy”,并通过 --group dummy 调用它来调用该测试。

phpunit.xml中的testsuite设置详解:

<testsuites>
    <testsuite name="default">
        <directory>./</directory>
    </testsuite>
</testsuites>

现在命令行调用:

/usr/bin/php74.bin.cli 
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so 
-dxdebug.collect_params=5 
-dxdebug.profiler_enable=on 
-dxdebug.trace_format=1 
-dxdebug.collect_return=1 
../../vendor/bin/phpunit 
--group no-db 
--verbose 
--debug 
--testsuite default 
--group dummy

【讨论】:

“命令行命令中 xdebug 的设置“-dxdebug.auto_trace=1”已过时,请参阅文档。” 为什么过时?根据您的信息 (Runtime: PHP 7.4.21 with Xdebug 2.8.0),该选项对 Xdebug v2 有效; “查看文档”链接适用于 Xdebug v3。 @lazyone 好点。需要重新审视。 Xdebug 2 不再受支持,所以请升级!在使用代码覆盖率时,您也真的不希望探查器打开。在 Xdebug 2 中,除了 -dzend_extension= 行之外,任何 xdebug 设置都不会影响 Xdebug 的代码覆盖率收集。

以上是关于FilterIterator 应该是 PHPUnit\Framework\TestSuiteIterator 的实例的主要内容,如果未能解决你的问题,请参考以下文章

PHPUnit简介及使用

面向初学者的 Selenium RC 和 PHP

如何在无类 php 文件上使用 PHPUnit Skeleton Generator?

如何配置代码-PHPUnit版本8.5.1对Zend Framework 2.4的覆盖范围?

这个是啥回事,我应该怎么弄啊!

为啥片段类应该是公开的?