带有 PHPUnit 8.4 的 PhpStorm 给出异常 Uncaught PHPUnit\Runner\Exception class ... 找不到

PhpStorm with PHPUnit 8.4 gives exception Uncaught PHPUnit\Runner\Exception class ... could not be found

我尝试使用 PHPUnit v8。但是我没有成功使用 PhpStorm。当我在 PhpStorm 中 运行 简单测试(class 方法)时,我收到以下消息:

PHP Fatal error:  Uncaught PHPUnit\Runner\Exception: Class 'Mrself\TreeType\Tests\Functional\BuildingTest' could not be found in '/vagrant/symfony-tree-type/tests/Functional/BuildingTest.php'. in /vagrant/symfony-tree-type/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php:65

是的,我有 class 是的,我已经正确配置了 psr:

"autoload": {
        "psr-4": {
            "Mrself\TreeType\": "./src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Mrself\TreeType\Tests\": "./tests/"
        }
    }

我已正确设置所有内容的证据是,当我 运行 vendor/bin/phpunit 它给了我正确的结果。

当我在 PhpStorm 中使用 运行 方法时,我收到以下调用:

/usr/bin/php /vagrant/symfony-tree-type/vendor/phpunit/phpunit/phpunit --configuration /vagrant/symfony-tree-type/phpunit.xml --filter "/(::testFormCanBeBuild)( .*)?$/" Mrself\TreeType\Tests\Functional\BuildingTest /vagrant/symfony-tree-type/tests/Functional/BuildingTest.php --teamcity

但是,如果我在 class 命名空间前面加上 \,一切也都可以正常工作。我不知道发生了什么事。 PHPUnit 版本 7 也适用。

同样的事情发生在我身上。突然间我开始收到以下错误:

PHP Fatal error:  Uncaught PHPUnit\Runner\Exception: Class 'Tests\Feature\ExampleTest' could not be found 

在我读完@frank-vue 的评论后,我注意到了同样的事情,他也做了:如果我 运行 测试整个文件夹,它 运行 正常,但如果我 运行 测试特定 class/method 我得到了那个错误。

我尝试了 PHPStorm 的早期版本,降级了 PHP 插件等...但没有任何效果。

在我的例子中,当我检查堆栈跟踪时看起来像:

#0 /var/www/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php(145): PHPUnit\Runner\StandardTestSuiteLoader->load('Tests\\Unit\\Ex...', '/var/www/tests/...')
#1 /var/www/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php(105): PHPUnit\Runner\BaseTestRunner->loadSuiteClass('Tests\\Unit\\Ex...', '/var/www/tests/...')
#2 /var/www/vendor/phpunit/phpunit/src/TextUI/Command.php(177): PHPUnit\Runner\BaseTestRunner->getTest('Tests\\Unit\\Ex...', '/var/www/tests/...', Array)
#3 /var/www/vendor/phpunit/phpunit/src/TextUI/Command.php(159): PHPUnit\TextUI\Command->run(Array, true)
#4 /var/www/vendor/phpunit/phpunit/phpunit(61): PHPUnit\TextUI\Command::main()
#5 {main}
  thrown in /var/www/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php on line 69

注意 Tests\\Unit\\Ex... 而不是 Tests\Unit\Ex...

所以最后我打破了规则,修改了供应商文件,应该不惜一切代价避免这种情况,但作为临时解决方案,它解决了我的问题。

所以我在第98行(PHP单元版本8.4.1)的vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php中添加了1行,替换了不必要的'\'。

if (empty($suiteClassFile) && \is_dir($suiteClassName) && !\is_file($suiteClassName . '.php')) {
    /** @var string[] $files */
    $files = (new FileIteratorFacade)->getFilesAsArray(
        $suiteClassName,
        $suffixes
    );

    $suite = new TestSuite($suiteClassName);
    $suite->addTestFiles($files);

    return $suite;
}
$suiteClassName = str_replace('\\', '\', $suiteClassName); // THIS IS THE LINE I ADDED
try {
    $testClass = $this->loadSuiteClass(
        $suiteClassName,
        $suiteClassFile
    );
} catch (Exception $e) {
    $this->runFailed($e->getMessage());
    return null;
}