PHPUnit打印测试执行时间

mck*_*k89 24 php phpunit execution-time

有没有办法用PHPUnit打印每个测试的执行时间?

edo*_*ian 21

要添加更多方法:


您可以编写自定义测试侦听器并将其添加到XML文件中.在那个听众你可以访问$testResult->time().phpunit.xml中的一些行和一个10行的PHP类.没有太多的麻烦.

class SimpleTestListener implements PHPUnit_Framework_TestListener
{
    public function endTest(PHPUnit_Framework_Test $test, $time)
    {
        printf("Test '%s' ended and took %s seconds.\n", 
           $test->getName(),
           $test->time()
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您仍然生成junit.xml(对于CI或在创建代码覆盖时),所有数字都在那里,并且使用简单的XSLT可以使这些数字更具可读性.

示例junit.xml

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="DemoTest" file="/home/edo/foo.php" tests="2" assertions="2" failures="1" errors="0" time="0.007727">
    <testcase name="testPass" class="DemoTest" file="/home/edo/foo.php" line="4" assertions="1" time="0.003801"/>
    <testcase name="testFail" class="DemoTest" file="/home/edo/foo.php" line="8" assertions="1" time="0.003926">
      <failure type="PHPUnit_Framework_ExpectationFailedException">DemoTest::testFail
Failed asserting that &lt;boolean:false&gt; is true.

/home/edo/foo.php:9
</failure>
    </testcase>
  </testsuite>
</testsuites>
Run Code Online (Sandbox Code Playgroud)

并进行如下转换:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h1>Tests</h1>
    <xsl:for-each select="testsuites/testsuite">
      <h2><xsl:value-of select="@name"/></h2>
      <ul>
        <xsl:for-each select="testcase">
          <li>
            <xsl:value-of select="@name"/> : <xsl:value-of select="@time"/>
            <xsl:if test="failure">
              <b>Failed !</b>
              <i><xsl:value-of select="*"/></i>
            </xsl:if>
          </li>
        </xsl:for-each>
      </ul>
    </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

你得到的线条显示你:( <li>testPass : 0.003801</li>HTML只是一个例子,它应该很容易适应).

在这里引用我自己的博客文章:http://edorian.github.io/2011-01-19-creating-your-custom-phpunit-output.formats/为xslt的东西.

  • 我的监听器扩展了`PHPUnit_Framework_BaseTestListener`,我发现`$ test-> time()`对于经过的时间不起作用.但是,基于本页其他地方的注释,`$ test-> getTestResultObject() - > time()`工作正常.`$ time`也适用于每个测试时间. (6认同)

jku*_*lak 16

只需添加--log-junit"my_tests_log.xml",然后使用电子表格应用程序(Excel,Numbers,Calc)打开此文件即可查看.您可以获得所需的所有信息,并且可以按测试执行时间排序.


小智 9

如果您不喜欢编写Testlistener,就像已经建议的那样,您可以使用以下脚本以更易于阅读的格式解析PHPUnit的JSON测试结果:

alias phpunit-report-runtime="phpunit --log-json php://stdout \
    | awk '\$NF ~ '/,/' && \$1 ~ /\"(test|time)\"/' \
    | cut -d: -f2- \
    | sed \"N;s/\n/--/\"  \
    | sed \"s/,//\"   \
    | awk 'BEGIN{FS=\"--\"}; {print \$2 \$1}' | sort -r \
    | head -n 5"
Run Code Online (Sandbox Code Playgroud)

格式是<time in seconds>, <test method>.示例输出:

 $ phpunit-report-runtime
 0.29307007789612, "VCR\\Util\\SoapClientTest::testDoRequestHookDisabled"
 0.16475319862366, "VCR\\CassetteTest::testRecordAndPlaybackRequest"
 0.092710018157959, "VCR\\Util\\SoapClientTest::testDoRequest"
 0.031861782073975, "VCR\\LibraryHooks\\SoapTest::testShouldInterceptCallWhenEnabled"
 0.026772022247314, "VCR\\LibraryHooks\\AbstractFilterTest::testRegisterAlreadyRegistered"
Run Code Online (Sandbox Code Playgroud)


小智 6

许多当前的答案讨论了如何访问和分析日志文件中的持续时间.我将分享两种方法来修改phpUnit版本3.7.38中的CLI输出(这是Travis-CI默认使用的PHP),基于@ edorian的不完整答案.


使用自定义打印机覆盖CLI输出.我找不到任何打印机文档,但似乎支持它们.您可以在源代码中查看可用的方法.

class TestDurationPrinter extends PHPUnit_TextUI_ResultPrinter
{
    public function endTest(PHPUnit_Framework_Test $test, $time)
    {
        printf("Test '%s' ended and took %s seconds.\n", 
           $test->getName(),
           $time
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将这些行作为属性phpunitphpunit.xml的文件:

printerFile="path/to/TestDurationPrinter.php"
printerClass="TestDurationPrinter"
Run Code Online (Sandbox Code Playgroud)

您也可以使用--printerCLI选项,但这对命名空间不起作用.


您可以通过实现PHPUnit_Framework_TestListener接口(这与打印机使用的接口相同),通过TestListener添加到CLI输出(而不是覆盖它).这将继续打印.,S以及F所以一定要考虑的是,如果你的愿望.

class TestDurationListener implements PHPUnit_Framework_TestListener
{
    public function endTest(PHPUnit_Framework_Test $test, $time)
    {
        printf("Test '%s' ended and took %s seconds.\n", 
           $test->getName(),
           $time
        );
    }

    public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
    {
    }

    public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
    {
    }

    public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
    {
    }

    public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
    {
    }

    public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
    {
    }

    public function startTest(PHPUnit_Framework_Test $test)
    {
    }

    public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
    {
    }

    public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在3.8及更高版本中,有一个PHPUnit_Framework_BaseTestListener可以扩展,以便您只定义要覆盖的方法.

class TestDurationListener extends PHPUnit_Framework_BaseTestListener
{
    public function endTest(PHPUnit_Framework_Test $test, $time)
    {
        printf("Test '%s' ended.\n", $test->getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

要包含新的侦听器,请将这些行添加到您的phpunit.xml文件中:

<listeners>
    <listener class="TestDurationListener" file="path/to/TestDurationListener.php" />
</listeners>
Run Code Online (Sandbox Code Playgroud)


tob*_*byS 5

您可以实现自己的测试运行器,例如通过扩展PHPUnit_TextUI_TestRunner并使其收集和打印运行时间.

  • 它已经收集了时间.你需要做的就是让它打印出来...... (6认同)