代码在 PHPUnit 初始化之前执行
我正在阅读我的项目的代码覆盖率报告,我注意到一些奇怪的事情:一行未被覆盖,但我确信该行在测试期间被执行。因此,我在它之前添加了一个 var_dump() ,这就是我在执行测试时得到的结果:
bool(true)
PHPUnit 3.5.5 by Sebastian Bergmann.
...
这很奇怪。怎么可能在 PHPUnit 初始化之前执行一行?我相信这就是代码覆盖率说该行未被覆盖的原因。
有什么提示吗?
编辑:这是一些代码。它是一个 IRC 框架,利用 Doctrine Common 库来读取注释,还使用 ClassLoader 和 EventDispatcher Symfony 组件。这就是罪名的方法:
/**
* Returns this module's reflection.
*
* @return \ReflectionClass
* @access public
*/
static public function getReflection()
{
// The var_dump() displaying bool(false) is executed before PHPUnit, while the other
// ones are correctly executed.
var_dump(is_null(self::$reflection));
if (null === self::$reflection) {
// This line is reported as uncovered, but it must be executed since I'm
// accessing the reflection!
self::$reflection = new \ReflectionClass(get_called_class());
}
return self::$reflection;
}
你觉得怎么样?
I was reading my project's code coverage report, and I noticed something strange: a line was uncovered, but I was sure that line got executed during the tests. So, I added a var_dump() before it and this is what I got when executing the tests:
bool(true)
PHPUnit 3.5.5 by Sebastian Bergmann.
...
This is weird. How is it possible that a line is executed before PHPUnit's initialization? I believe this is the reason why code coverage says that line is uncovered.
Any hints?
EDIT: Here's some code. It's an IRC framework that makes use of the Doctrine Common library to read annotations and also uses the ClassLoader and EventDispatcher Symfony components. This is the incriminated method:
/**
* Returns this module's reflection.
*
* @return \ReflectionClass
* @access public
*/
static public function getReflection()
{
// The var_dump() displaying bool(false) is executed before PHPUnit, while the other
// ones are correctly executed.
var_dump(is_null(self::$reflection));
if (null === self::$reflection) {
// This line is reported as uncovered, but it must be executed since I'm
// accessing the reflection!
self::$reflection = new \ReflectionClass(get_called_class());
}
return self::$reflection;
}
What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设(但这只是一个猜测,因为很难说,因为您没有显示代码),它与在文件包含时执行的代码有关,而不是在执行实际测试函数或实例化测试用例之后执行。
I assume (but that's just a guess as it's hard to say since you have not shown the code), that it's related to code that gets executed on file-inclusion, rather after actual test functions are executed or testcases get instantiated.
必须在初始化 self::$reflection 的单元测试之外调用访问器。此后,对
getReflection()
的所有进一步调用都会跳过if
块,因此永远不会将其计为已覆盖。 PHPUnit 在运行任何测试或跟踪代码覆盖率之前实例化所有测试用例类(每个测试方法、数据提供程序方法和数据提供程序参数数组一个)。寻找一个从其构造函数调用 getReflection() 的测试用例,或者在加载时执行代码的类本身之外调用 getReflection() 的测试用例。我忘记了测试用例是否在 PHPUnit 输出其版本之前实例化,现在无法检查,但我相信情况确实如此。另一种可能性是您正在从
bootstrap.php
调用getReflection()
,但您可能已经检查过这一点。The accessor must be getting called outside of a unit test which initializes
self::$reflection
. After that, all further calls togetReflection()
skip theif
block so it'll never be counted as covered. PHPUnit instantiates all of the test case classes--one per test method, data provider method, and data provider argument array--before running any of the tests or tracing code coverage. Look for a test case that callsgetReflection()
from its constructor or outside the class itself where the code is executed upon loading.I forget if the test cases are instantiated before PHPUnit outputs its version and cannot check now, but I believe this is the case. The other possibility is that you're calling
getReflection()
frombootstrap.php
, but you probably already checked for that.