Время выполнения тестов печати PHPUnit

есть ли способ распечатать время выполнения каждого теста с помощью PHPUnit?

Solutions Collecting From Web of "Время выполнения тестов печати PHPUnit"

Вы можете реализовать свой собственный тестовый бегун, например, расширив PHPUnit_TextUI_TestRunner и сделав его сбор и печать времени выполнения.

Чтобы добавить еще несколько способов:


Вы можете написать собственный тестовый прослушиватель и добавить его в файл 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() ); } } 

Если вы создаете 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> во <?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> 

и с таким преобразованием:

 <?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> 

вы получите строки, показывающие вам: <li>testPass : 0.003801</li> (HTML – просто пример, его нужно легко адаптировать).

Ссылка на мой собственный пост в блоге: http://edorian.github.io/2011-01-19-creating-your-custom-phpunit-output.formats/ для материала xslt.

Просто добавьте -log-junit «my_tests_log.xml», а затем откройте этот файл с помощью приложения электронной таблицы (Excel, Numbers, Calc), чтобы просмотреть его. Вы получаете всю запрашиваемую информацию, и вы можете сортировать по времени выполнения теста.

Если вам не нравится писать Testlistener, как уже было предложено, вы можете использовать следующий скрипт для анализа результата теста JSON PHPUnit в более удобном для чтения формате:

 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" 

Формат – <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" 

Многие из текущих ответов обсуждают, как получить доступ и проанализировать время продолжительности в файле журнала. Я расскажу о двух способах изменения вывода CLI в версии 3.7.38 phpUnit (это то, что 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 ); } } 

Затем добавьте эти строки в качестве атрибутов phpunit в файле phpunit.xml :

 printerFile="path/to/TestDurationPrinter.php" printerClass="TestDurationPrinter" 

Вы также можете использовать --printer CLI, но это не очень хорошо работает с пространствами имен.


Вы можете добавить к выводу CLI, в отличие от его переопределения, с помощью TestListener, реализуя интерфейс PHPUnit_Framework_TestListener (это тот же интерфейс, что и принтеры). Это все равно будет напечатано . , 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) { } } 

В версии 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()); } } 

Чтобы добавить нового слушателя, добавьте эти строки в файл phpunit.xml :

 <listeners> <listener class="TestDurationListener" file="path/to/TestDurationListener.php" /> </listeners> 

Ну, вы можете экспортировать время выполнения с помощью журнала . В результате он не выводится напрямую, но вы можете написать красивое средство просмотра отчетов, которое выводит результаты файла журнала (либо из JSON, либо из XML). Это должно получить вас, что вы хотите …

Я думаю, вы могли бы использовать методы setUp и tearDown (которые вызываются соответственно в начале и в конце каждого теста) :

  • setUp текущее время перед тестом, в setUp ,
  • И вычислите время, которое прошел тест, в tearDown .

Конечно, вам придется делать это в каждом из ваших тестовых классов – или в суперклассе, который будет унаследован всеми вашими тестовыми классами.

Вот полный пример, основанный на идее ответа edorians. Протестировано на PHPunit 4.

Создайте следующий класс PHP:

 class ProfilingTestListener extends PHPUnit_Framework_BaseTestListener { public function endTest(PHPUnit_Framework_Test $test, $time) { printf("Test '%s' ended.\tTotal time %s s.\tTest time %s s.\n", str_pad($test->toString(), 50), number_format($test->getTestResultObject()->time(), 3), number_format($time, 3) ); } } 

Добавьте в свой phpunit.xml следующее:

 <phpunit ..> ... <listeners> <listener class="ProfilingTestListener"></listener> </listeners> ... </phpunit> 

Пример вывода:

 PHPUnit 4.7.7 by Sebastian Bergmann and contributors. Test 'FooTest::testFoo ' ended. Total time 2.050 s. Test time 0.026 s. .Test 'FooTest::testBar ' ended. Total time 2.077 s. Test time 1.000 s. .Test 'FooTest::testBar2 ' ended. Total time 3.077 s. Test time 0.730 s. 

На мой взгляд, самым простым решением является экспорт тестовой статистики как json:

$ phpunit –log-json testExport.json

Мне понравился ответ @ adri. Я начал с этого:

 alias phpunittime=" | awk '\$NF ~ '/,/' && \$1 ~ /\"(test|time)\"/' \ | cut -d: -f2- \ | sed \"N;s/\n/--/\" \ | sed \"s/,//\" \ | awk 'BEGIN{FS=\"--\"}; {print \$2 \$1}' | sort -r \ | head" 

Для использования вам необходимо настроить модуль PHP для вывода в файл журнала JSON. Для этого сделайте свой phpunit.xml следующим:

 <phpunit> <logging> <log type="json" target="/tmp/logfile.json"/> </logging> </phpunit> 

Затем используйте вот так:

 $ cat /tmp/logfile.json | phpunittime 

Чтобы увидеть больше или меньше 10 таймингов, скажем, 2 или 19, используйте -n 2 или -n 19 , соответственно, в конце.

Что хорошо в этом, так это в том, что он не делает предположений о том, как вы вызываете / запускаете phpunit (в моем случае я использую CakePHP и запускаю свою команду следующим образом: Console/cake test app ). Кроме того, вы можете запускать свои тесты и видеть их результаты как обычно … ваш терминал не просто сидит там, пока тесты не будут выполнены.

Основываясь на ответах выше, я создал небольшую библиотеку для отображения времени выполнения. https://github.com/santik/phpunit-profiler