在运行PHPUnit测试时,我希望能够转储输出,以便调试一两个东西。
我已经尝试了以下(类似于PHPUnit手册的例子);
class theTest extends PHPUnit_Framework_TestCase
{
/**
* @outputBuffering disabled
*/
public function testOutput() {
print_r("Hello World");
print "Ping";
echo "Pong";
$out = "Foo";
var_dump($out);
}
}
结果如下:
PHPUnit @package_version@ by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 0 assertions)
注意,这里没有预期的输出。
我使用的是2011年9月19日的git回购的HEAD版本。
php -version输出:
$ php -version
PHP 5.2.9 (cli) (built: Dec 8 2010 11:36:37)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
是否有什么我做错了,或者这是一个潜在的PHPUnit错误?
下面是PHPUnit 4.x中用于打印调试消息的几个有用方法:
syslog(LOG_DEBUG, "Debug: Message 1!");
More practical example:
syslog(LOG_DEBUG, sprintf("%s: Value: %s", __METHOD__, var_export($_GET, TRUE)));
Calling syslog() will generate a system log message (see: man syslog.conf).
Note: Possible levels: LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, etc.
On macOS, to stream the syslog messages in realtime, run:
log stream --level debug --predicate 'processImagePath contains "php"'
fwrite(STDERR, "LOG: Message 2!\n");
Note: The STDERR constant is not available if reading the PHP script from stdin. Here is the workaround.
Note: Instead of STDERR, you can also specify a filename.
file_put_contents('php://stderr', "LOG: Message 3!\n", FILE_APPEND);
Note: Use this method, if you don't have STDERR constant defined.
register_shutdown_function('file_put_contents', 'php://stderr', "LOG: Message 4!\n", FILE_APPEND);
Note: Use this method, if you'd like to print something at the very end without affecting the tests.
要转储变量,使用var_export(),例如:值:。var_export($some_var, TRUE)。“\ n”。
若要仅在verbose或调试模式下打印上述消息,请参见:是否有一种方法可以判断在测试中——debug或——verbose是否传递给了PHPUnit ?
如果测试输出是测试本身的一部分,请查看:测试输出文档页面。
更新
刚刚发现了另一种方法,它比——verbose命令行选项更好:
class TestSomething extends PHPUnit_Framework_TestCase {
function testSomething() {
$myDebugVar = array(1, 2, 3);
fwrite(STDERR, print_r($myDebugVar, TRUE));
}
}
这让您可以随时将任何内容转储到控制台,而不会出现——verbose CLI选项带来的所有不必要的输出。
正如其他答案所指出的,最好使用内置方法来测试输出,例如:
$this->expectOutputString('foo');
然而,有时调皮一点,看看测试用例中的一次性/临时调试输出是有帮助的。但是,不需要使用var_dump黑客/变通方法。这可以通过在运行测试套件时设置——verbose命令行选项轻松实现。例如:
$ phpunit --verbose -c phpunit.xml
当在CLI环境中运行时,这将显示测试方法内部的输出。
参见:为PHPUnit编写测试-测试输出。
更新:参见rdlowrey的更新下面关于使用fwrite(STDERR, print_r($myDebugVar, TRUE));作为一个简单得多的工作
这种行为是有意为之的(正如jasonbar所指出的)。手册的冲突状态已报告给PHPUnit。
一种变通方法是让PHPUnit断言预期输出为空(当实际上有输出时),这将触发要显示的意外输出。
class theTest extends PHPUnit_Framework_TestCase
{
/**
* @outputBuffering disabled
*/
public function testOutput() {
$this->expectOutputString(''); // tell PHPUnit to expect '' as output
print_r("Hello World");
print "Ping";
echo "Pong";
$out = "Foo";
var_dump($out);
}
}
给:
PHPUnit @package_version@ by Sebastian Bergmann.
F
Time: 1 second, Memory: 3.50Mb
There was 1 failure:
1) theTest::testOutput
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-''
+'Hello WorldPingPongstring(4) "Foo"
+'
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
一定要禁用用于测试的任何其他断言,因为它们可能在测试输出断言之前失败(因此您将看不到输出)。
在某些情况下,可以使用类似的东西向控制台输出一些内容
class yourTests extends PHPUnit_Framework_TestCase
{
/* Add Warnings */
protected function addWarning($msg, Exception $previous = null)
{
$add_warning = $this->getTestResultObject();
$msg = new PHPUnit_Framework_Warning($msg, 0, $previous);
$add_warning->addWarning($this, $msg, time());
$this->setTestResultObject($add_warning);
}
/* Add errors */
protected function addError($msg, Exception $previous = null)
{
$add_error = $this->getTestResultObject();
$msg = new PHPUnit_Framework_AssertionFailedError($msg, 0, $previous);
$add_error->addError($this, $msg, time());
$this->setTestResultObject($add_error);
}
/* Add failures */
protected function addFailure($msg, Exception $previous = null)
{
$add_failure = $this->getTestResultObject();
$msg = new PHPUnit_Framework_AssertionFailedError($msg, 0, $previous);
$add_failure->addFailure($this, $msg, time());
$this->setTestResultObject($add_failure);
}
public function test_messages()
{
$this->addWarning("Your warning message!");
$this->addError("Your error message!");
$this->addFailure("Your Failure message");
}
/* Or just mark test states! */
public function test_testMarking()
{
$this->markTestIncomplete();
$this->markTestSkipped();
}
}