I have a PHPUnit test suite that is currently causing a fatal error due to a class definition that's not being found. This, ultimately, is a failure of the testing code itself and a failure by the developer to vindicate the test itself before committing code.
我有一个PHPUnit测试套件,它目前正在导致一个致命错误,因为一个类定义没有被找到。最终,这是测试代码本身的失败,也是开发人员在提交代码之前维护测试本身的失败。
However, things like this do happen from time to time, and it would be wonderful if, when a fatal error occurs (regardless of who's ultimately responsible), the test simply be marked as a failure, and the remainder of the test suite still be executed.
然而,这样的事情经常发生,如果发生致命的错误(不管最终的责任是谁),测试仅仅被标记为失败,并且测试套件的其余部分仍然被执行,那将是非常棒的。
I have read about the --process-isolation
switch and as far as I can tell, it should take care of this. Since each test runs in a separate process, if the child dies due to a fatal error, the parent can still continue to run. In fact, this is stated explicitly in this answer to a similar question: https://*.com/a/5340151/84762 which shows the exact type of output I would like to see myself.
我读过关于——进程隔离开关的文章,据我所知,它应该解决这个问题。由于每个测试在一个单独的进程中运行,如果该子进程由于一个致命错误而死亡,那么父进程仍然可以继续运行。事实上,在这个类似问题的答案中明确地说明了这一点:https://*.com/a/5340151/84762,它显示了我希望看到自己的输出类型。
However, I seem to get the exact same output regardless of whether or not I use the --process-isolation
flag:
但是,无论我是否使用-process-isolation标志,我得到的输出似乎完全相同:
WITHOUT process isolation
没有处理隔离
[kogi@phagocyte ~]$ /usr/bin/phpunit --colors --verbose --coverage-html "target/coverage" ~/app/zend/tests/application/
PHP Fatal error: Class 'Rmd_Database_OldObject' not found in /home/kogi/app/zend/private/models/translate/Poll.php on line 9
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/pear/PHPUnit/TextUI/Command.php:130
PHP 4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/pear/PHPUnit/TextUI/Command.php:150
PHP 5. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/pear/PHPUnit/Runner/BaseTestRunner.php:96
PHP 6. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/pear/PHPUnit/Framework/TestSuite.php:419
PHP 7. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/pear/PHPUnit/Framework/TestSuite.php:358
PHP 8. PHPUnit_Util_Fileloader::load() /usr/share/pear/PHPUnit/Util/Fileloader.php:79
PHP 9. include_once() /usr/share/pear/PHPUnit/Util/Fileloader.php:95
PHP 10. require_once() /home/kogi/app/zend/tests/application/translate/PollTest.php:11
Fatal error: Class 'Rmd_Database_OldObject' not found in /home/kogi/app/zend/private/models/translate/Poll.php on line 9
Call Stack:
0.0003 91584 1. {main}() /usr/bin/phpunit:0
0.0076 612672 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
0.0076 613744 3. PHPUnit_TextUI_Command->run() /usr/share/pear/PHPUnit/TextUI/Command.php:130
0.0246 1249464 4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/pear/PHPUnit/TextUI/Command.php:150
0.0706 1626680 5. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/pear/PHPUnit/Runner/BaseTestRunner.php:96
0.1691 8053584 6. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/pear/PHPUnit/Framework/TestSuite.php:419
0.1693 8057320 7. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/pear/PHPUnit/Framework/TestSuite.php:358
0.1694 8057664 8. PHPUnit_Util_Fileloader::load() /usr/share/pear/PHPUnit/Util/Fileloader.php:79
0.1711 8240600 9. include_once('/home/kogi/app/zend/tests/application/translate/PollTest.php') /usr/share/pear/PHPUnit/Util/Fileloader.php:95
0.1805 9187768 10. require_once('/home/kogi/app/zend/private/models/translate/Poll.php') /home/kogi/app/zend/tests/application/translate/PollTest.php:11
WITH process isolation
与处理隔离
[kogi@phagocyte ~]$ /usr/bin/phpunit --colors --verbose --coverage-html "target/coverage" --process-isolation ~/app/zend/tests/application/
PHP Fatal error: Class 'Rmd_Database_OldObject' not found in /home/kogi/app/zend/private/models/translate/Poll.php on line 9
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/pear/PHPUnit/TextUI/Command.php:130
PHP 4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/pear/PHPUnit/TextUI/Command.php:150
PHP 5. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/pear/PHPUnit/Runner/BaseTestRunner.php:96
PHP 6. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/pear/PHPUnit/Framework/TestSuite.php:419
PHP 7. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/pear/PHPUnit/Framework/TestSuite.php:358
PHP 8. PHPUnit_Util_Fileloader::load() /usr/share/pear/PHPUnit/Util/Fileloader.php:79
PHP 9. include_once() /usr/share/pear/PHPUnit/Util/Fileloader.php:95
PHP 10. require_once() /home/kogi/app/zend/tests/application/translate/PollTest.php:11
Fatal error: Class 'Rmd_Database_OldObject' not found in /home/kogi/app/zend/private/models/translate/Poll.php on line 9
Call Stack:
0.0003 91752 1. {main}() /usr/bin/phpunit:0
0.0076 612824 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
0.0076 613896 3. PHPUnit_TextUI_Command->run() /usr/share/pear/PHPUnit/TextUI/Command.php:130
0.0246 1250360 4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/pear/PHPUnit/TextUI/Command.php:150
0.0708 1627528 5. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/pear/PHPUnit/Runner/BaseTestRunner.php:96
0.1688 8054296 6. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/pear/PHPUnit/Framework/TestSuite.php:419
0.1690 8057992 7. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/pear/PHPUnit/Framework/TestSuite.php:358
0.1691 8058336 8. PHPUnit_Util_Fileloader::load() /usr/share/pear/PHPUnit/Util/Fileloader.php:79
0.1707 8241296 9. include_once('/home/kogi/app/zend/tests/application/translate/PollTest.php') /usr/share/pear/PHPUnit/Util/Fileloader.php:95
0.1801 9188464 10. require_once('/home/kogi/app/zend/private/models/translate/Poll.php') /home/kogi/app/zend/tests/application/translate/PollTest.php:11
For those of us that can't effectively diff in our heads, the two outputs are literally identical (other than the execution time and memory usage which is negligibly different).
对于那些无法在头脑中有效地划分的人来说,这两个输出实际上是完全相同的(除了执行时间和内存使用是可以忽略的不同)。
In both cases, the fatal error kills the entire test suite. In this particular case, this happens in the 3rd test and the remaining 150 tests (in several other files/suites) are never executed.
在这两种情况下,致命错误都会杀死整个测试套件。在这个特殊的例子中,这发生在第3个测试中,其余的150个测试(在其他几个文件/套件中)不会被执行。
What am I doing wrong here? Is there some other way to survive a fatal error (marking the test as failed) in one test and still execute remaining tests?
我在这里做错了什么?是否有其他方法可以在一个测试中通过一个致命错误(将测试标记为失败)并仍然执行剩余的测试?
EDIT
编辑
I am using PHPUnit 3.6.10
我正在使用PHPUnit 3.6.10
EDIT
编辑
Comments on the answer to this question have inspired a new ticket on PHPUnit's GitHub page: https://github.com/sebastianbergmann/phpunit/issues/545
关于这个问题的答案的评论已经在PHPUnit的GitHub页面上激起了一张新的罚单:https://github.com/sebastianbergmann/phpunit/issues/545
1 个解决方案
#1
5
PHPUnit loads each test file that will be run before running any tests. This causes PHP to parse these files and execute their top-level code. If any class is loaded that, for example, extends a class that doesn't exist, you'll get a fatal error.
PHPUnit加载在运行任何测试之前运行的每个测试文件。这导致PHP解析这些文件并执行它们的*代码。如果加载了某个类(例如,扩展了一个不存在的类),您将得到一个致命错误。
I don't see any way around this without enhancing PHPUnit to parse the files without executing their code during the scanning process.
我认为如果不增强PHPUnit,就无法在扫描过程中解析文件而不执行它们的代码。
#1
5
PHPUnit loads each test file that will be run before running any tests. This causes PHP to parse these files and execute their top-level code. If any class is loaded that, for example, extends a class that doesn't exist, you'll get a fatal error.
PHPUnit加载在运行任何测试之前运行的每个测试文件。这导致PHP解析这些文件并执行它们的*代码。如果加载了某个类(例如,扩展了一个不存在的类),您将得到一个致命错误。
I don't see any way around this without enhancing PHPUnit to parse the files without executing their code during the scanning process.
我认为如果不增强PHPUnit,就无法在扫描过程中解析文件而不执行它们的代码。