is there a way to print the execution time of each test with PHPUnit?
You can implement your own test runner, for example by extending PHPUnit_TextUI_TestRunner
and make it collect and print run times.
To add some more ways:
You can write a custom Test listener and add it to the XML file. In that listener you can access the $testResult->time()
. Some lines in your phpunit.xml and a 10 line PHP class. Not too much hassle.
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()
);
}
}
If you generate a junit.xml anyways (for CI or while creating code coverage) all the numbers are there anyways and with a simple XSLT you can make those even more readable.
Example 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 <boolean:false> is true.
/home/edo/foo.php:9
</failure>
</testcase>
</testsuite>
</testsuites>
and with an transformation like this:
<?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>
you get lines showing you: <li>testPass : 0.003801</li>
(the HTML is just an example, it should be easily adaptable).
Referencing my own blog post here: http://edorian.github.io/2011-01-19-creating-your-custom-phpunit-output.formats/ for the xslt stuff.
If you don't like to write a Testlistener, like it was suggested already, you can use the following script to parse the PHPUnit's JSON Test Result in an easier to read format:
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"
Format is <time in seconds>, <test method>
. Example output:
$ 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"