PHPUnit在使用过程隔离时发生致命错误后不继续进行测试

时间:2022-02-23 07:02:32

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,就无法在扫描过程中解析文件而不执行它们的代码。