为PHPUnit创建基本测试类并将其扩展为常见功能会导致找不到类错误

r.b*_*gil 25 php phpunit unit-testing

我正在使用引导程序文件运行PHPUnit,用于自动加载类(由composer生成).

我的所有测试都很好地加载了类,但是对于我的两个测试,我创建了一个"基础"测试类,它扩展了PHPUnit_Framework_TestCase,然后是两个扩展基类的测试类,类似于以下示例代码的结构:

abstract class BaseTest extends PHPUnit_Framework_TestCase
{
    abstract function setUp();
    protected function getCommonTestVariables()
    {
        // ...
    }

    protected function runCommonTests()
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)
class BlahBlahTest extends BaseTest
{
    public function setUp()
    {
         $variables=$this->getCommonTestVariables();
         //etc...
    }

    public function testThings()
    {
        $this->runCommonTests();
    }
}
Run Code Online (Sandbox Code Playgroud)

每当我运行它时,PHPUnit都会出错:

致命错误:第13行的BlahBlahTest.php中找不到类'BaseTest'

我检查了文件名,位置,名称空间,一切似乎都是有序的.任何帮助将被理解为深究这一点

Pot*_*rca 29

我遇到了同样的问题,如果你对PHPUnit和Composer的内部工作原理不太熟悉,这看起来确实令人困惑.

PHPunit不使用Composer自动加载器来查找任何测试类.它只扫描您提供的任何目录,并一次操作一个文件.

因此,它不知道任何其他类,而不是它当前正在运行的文件中的类.这就是bootstrap文件发挥作用的地方.

如果要使用Composer Autoloader加载其他测试类,则需要告诉它可以在哪里找到这些测试类(以及可选的,在哪个命名空间中).

有两种方法可以做到这一点:

  1. autoload-dev在您的composer.json或中添加一个部分
  2. 将测试目录添加到Composer Autoloader

使用 autoload-dev

这些autoload-dev部分允许您为开发目的定义自动加载规则.

直接从手册中引用:

运行测试套件所需的类不应包含在主自动加载规则中,以避免在生产中污染自动加载器以及其他人将您的包用作依赖项.

因此,最好依靠专用路径进行单元测试并将其添加到autoload-dev部分.

例:

{
    "autoload": {
        "psr-4": { "MyLibrary\\": "src/" }
    },
    "autoload-dev": {
        "psr-4": { "MyLibrary\\Tests\\": "tests/" }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加到Composer Autoloader

另一种方法是获取Composer Autoloader和add您的测试命名空间(如果有的话)和测试所在的目录.如手册("基本用法"中自动加载部分底部)所述,如何执行此操作是:

$loader = require('/path/to/vendor/autoload.php');
$loader->add('Test\\', __DIR__ . '/Tests');
Run Code Online (Sandbox Code Playgroud)

如果您的测试使用镜像测试目录的命名空间但仍然遇到麻烦,您可以尝试通过替换第一个参数('Test\\')来省略前缀''.


如果您想进一步了解所有这些是如何工作的,您应该查看Composer ClassLoader类,尤其是add()findFile()方法.