【问题标题】:Phpunit very slow when --coverage-html当 --coverage-html 时,phpunit 很慢
【发布时间】:2014-10-30 05:29:54
【问题描述】:

我正在使用 Phpunit。如果我只是运行我的测试:

phpunit --log-junit output.xml

这会在一秒钟内运行。但如果我想要代码覆盖率:

phpunit --coverage-html ./report --log-junit output.xml

然后它非常慢,phpunit 发送“从 *.xml 读取配置”并挂起一分钟,然后它开始执行测试

【问题讨论】:

  • 构建代码覆盖率数据会变慢,这是什么问题?您只在需要时构建代码覆盖率报告
  • 我知道调试会使它变慢。但它要慢 10000000 倍...
  • 我认为这可能是 xDebug 速度慢的问题,而不是 PHPUnit 的问题。 xdebug_start_code_coverage() 函数 is called 带有 XDEBUG_CC_DEAD_CODEXDEBUG_CC_UNUSED 选项,以及 "Enabling those options make code coverage drastically slower."
  • @J.D.把钉子钉在头上。我目前正在开发一个补丁,它可以让这个速度提高 10 倍。您可以在此处跟踪进度。 github.com/sebastianbergmann/php-code-coverage/pull/387 这将被合并到 php 代码覆盖的 3.0 版本中(支持 php >=5.6)。我也可能会 fork 这个版本并使其与 php5.5 兼容

标签: php xml phpunit


【解决方案1】:

默认情况下,PHPUnit 将评估您配置的白名单中所有文件的覆盖率,即使您为单个测试运行 PHPUnit。

如果您的白名单中有很多文件,这可能会增加代码覆盖率的生成时间。

您可以通过将addUncoveredFilesFromWhitelist 属性设置为false 来配置PHPUnit 以仅为您编写/执行测试的文件生成代码覆盖率来加快速度。

<phpunit>
    <!-- ... -->
    <filter>
        <whitelist addUncoveredFilesFromWhitelist="false">
            <!-- ... -->
        </whitelist>
    </filter>
</phpunit>

禁用此设置后,您应该会看到生成的代码覆盖率文件仅描述您对其运行测试的文件。

请注意,PHPUnit documentation 建议 addUncoveredFilesFromWhitelist 默认为 false,但在 5.5 版中默认为 true

【讨论】:

    【解决方案2】:

    只是为了增加最后一个答案。通常,发生这种情况是因为 PHPunit 看到了所有文件,您需要告诉他们不要这样做,如下例所示:

    像这样在 phpunit.xml 中查看我的过滤器节点

    <filter>
        <whitelist>
            <directory>../src</directory>
        </whitelist>
    </filter>
    

    我需要添加 addUncoveredFilesFromWhitelist 等于 false 并添加我需要排除的所有文件,如下所示:

    <filter>
       <whitelist addUncoveredFilesFromWhitelist="false">
            <directory suffix=".php">../src</directory>
            <exclude>
                <directory>../vendor</directory>
                <directory>../anotherpath</directory>
                <directory>../src/Modules/*/Fixture</directory>
                <file>../src/Modules/*/Bootstrap.php</file>
            </exclude>
        </whitelist>
    </filter>
    

    注意我的排除列表,我排除了所有模块的“Fixture”目录和 Bootstrap.php 文件

    在做了这个简单的改变之后,我的单元测试从 10 分钟变成了 3 分钟,所以享受吧:)

    【讨论】:

      【解决方案3】:

      当运行带有代码覆盖率的 phpunit 时,对速度影响最大的事情是,对于每个测试方法,phpunit 使用带有 XDEBUG_CC_UNUSEDXDEBUG_CC_DEAD_CODE 的 xdebug,它检查每个文件中的死代码和未使用代码在该特定测试执行期间被触及。这包括供应商类、测试类、phpunit 框架类和白名单之外的任何其他类。 phpunit 实际上只关心被测对象(或白名单中的类)。我正在调整代码覆盖率,以便在打开提到的 2 个标志的情况下更智能地运行 xdebug,因此它只需要检查 phpunit 关心的文件的死代码和未使用代码。您可以在此处查看进度。 https://github.com/sebastianbergmann/php-code-coverage/pull/387

      【讨论】:

        【解决方案4】:

        这是正常行为。

        想想 PHPUnit 在做什么:

        它正在运行您的测试,跟踪每一行代码的执行,然后获取所有原始数据(每行执行的次数)并构建一个通过阅读您的代码并将其重新格式化为 HTML 进行报告,并补充所有执行数据。

        需要很长时间并不奇怪。

        【讨论】:

        • 但它甚至没有启动。它在开始之后和发送点之前一直挂着,这就是我觉得奇怪的地方
        • 不确定你的意思。在您最初的问题中,您说它暂停一分钟,然后开始运行测试。假设您的字面意思是“一分钟”,这并不让我感到惊讶。当我运行测试时,我发现同样的事情 - 不是一分钟,但也许你的计算机比我慢,或者代码行更多,等等。虽然我对 PHPunit 的内部结构一无所知,但它不会知道它是从索引您的代码开始的,这让我感到惊讶。
        • 是否每次都必须索引代码?在我看来,应该有某种智能缓存——但在这种情况下,这可能是不可能的或没有帮助的。
        【解决方案5】:

        phpdbg 比 xdebug 更快

        欲了解更多信息,请查看以下链接 https://hackernoon.com/generating-code-coverage-with-phpunite-and-phpdbg-4d20347ffb45

        linux的安装流程:

        sudo apt-get update -y
        sudo apt-get install -y php-phpdbg
        

        欲了解更多信息,请查看以下链接 https://zoomadmin.com/HowToInstall/UbuntuPackage/php-phpdbg

        生成代码覆盖率

        phpdbg -qrr vendor/bin/phpunit --coverage-html ./var/log
        
        

        我希望它对每个人都非常有用。

        【讨论】:

          猜你喜欢
          • 2018-04-21
          • 2014-05-12
          • 1970-01-01
          • 2021-06-05
          • 2015-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-19
          相关资源
          最近更新 更多