使用 Composer 和 autoload 在 PHPUnit 中自动加载类.php

我刚刚通过Composer安装了Sebastian Bergmann的PHPUnit版本3.7.19,并编写了一个我想进行单元测试的类。

我希望我的所有类都自动加载到每个单元测试中,而不必使用或处于测试的顶部,但事实证明这很困难!includerequire

这就是我的目录结构的样子(尾随/斜杠表示目录,而不是文件):

* composer.json
* composer.lock
* composer.phar
* lib/
    * returning.php
* tests/
    * returningTest.php
* vendor/
    * bin/
        * phpunit
    * composer/
    * phpunit/
    * symfony/
    * autoload.php

我的 composer.json 文件包括以下内容:

"require": {
    "phpunit/phpunit": "3.7.*",
    "phpunit/phpunit-selenium": ">=1.2"
}

返回.php类文件包括以下内容:

<?php
class Returning {
    public $var;
    function __construct(){
        $this->var = 1;
    }
}
?>

我的返回测试.php测试文件包括以下内容:

<?php
class ReturningTest extends PHPUnit_Framework_TestCase
{
    protected $obj = null;
    
    protected function setUp()
    {
        $this->obj = new Returning;
    }
    
    public function testExample()
    {   
        $this->assertEquals(1, $this->obj->var);
    }

    protected function tearDown()
    {
        
    }
}
?>

但是,当我从命令行运行时,我收到以下错误:./vendor/bin/phpunit tests

PHP 致命错误:在第 8 行的 /files/code/php/db/tests/returningTest.php 中找不到类“Returning”

我注意到 生成了一个文件,但不确定这是否与我的问题有关。composerautoload.phpvendor/autoload.php

此外,在Stack Overflow的其他一些答案中,人们提到了一些关于在作曲家中使用PSR-0和在PHP中使用命令的事情,但我没有成功地使用任何一个。namespace

请帮忙!我只想在PHPUnit中自动加载我的类,这样我就可以使用它们来创建对象,而不必担心或.includerequire


更新日期:2013 年 8 月 14 日

我现在已经创建了一个名为PHPUnit Skeleton的开源项目,以帮助您轻松地启动并运行PHPUnit测试。


答案 1

好吧,起初。您需要告诉自动加载器在哪里可以找到类的php文件。这是通过遵循PSR-0标准来完成的。

最好的方法是使用命名空间。自动加载程序会在您请求类时搜索文件。那里有一些很棒的命名空间教程,只需搜索和阅读即可。请注意,命名空间不是PHP中用于自动加载的东西,而是可用于自动加载的东西。Acme/Tests/ReturningTest.phpAcme\Tests\ReturningTest

Composer 附带一个标准的 PSR-0 自动加载机(中的那个)。在您的情况下,您希望告诉自动加载程序在目录中搜索文件。然后当你使用它时,它会寻找.vendor/autoload.phplibReturningTest/lib/ReturningTest.php

将其添加到您的 :composer.json

{
    ...
    "autoload": {
        "psr-0": { "": "lib/" }
    }
}

文档中提供了详细信息。

现在,自动加载器可以找到您需要的类,以便在运行测试之前让PHPunit知道有一个文件要执行:引导文件。您可以使用该选项指定引导程序文件所在的位置:--bootstrap

$ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php

但是,最好使用PHPunit配置文件

<!-- /phpunit.xml.dist -->
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="./vendor/autoload.php">

    <testsuites>
        <testsuite name="The project's test suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>

</phpunit>

现在,您可以运行该命令,它将自动检测配置文件:

$ ./vendor/bin/phpunit

如果将配置文件放入另一个目录,则需要在带有该选项的命令中放置该目录的路径。-c


答案 2

[更新2]另一种更简单的替代方法是在(reference)中使用该指令。好处是,您不需要维护两个引导.php(一个用于prod,一个用于开发)只是为了自动加载不同的类。autoload-devcomposer.json

{
  "autoload": {
    "psr-4": { "MyLibrary\\": "src/" }
  },
  "autoload-dev": {
    "psr-4": { "MyLibrary\\Tests\\": "tests/" }
  }
}

[更新]Wouter J的答案更完整。但我可以帮助那些想要在文件夹中设置PSR-0自动加载的人。
Phpunit 扫描具有此模式的所有文件。因此,我们不需要自己自动加载它们。但是我们仍然希望自动加载其他支持类,例如夹具/存根或某些父类。tests/*Test.phptests/

一个简单的方法是查看 Composer 项目本身是如何设置 phpunit 测试的。这其实很简单。请注意带有“bootstrap”的行。

参考资料: https://github.com/composer/composer/blob/master/phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
         bootstrap="tests/bootstrap.php"
>
    <testsuites>
        <testsuite name="Composer Test Suite">
            <directory>./tests/Composer/</directory>
        </testsuite>
    </testsuites>

    <groups>
        <exclude>
            <group>slow</group>
        </exclude>
    </groups>

    <filter>
        <whitelist>
            <directory>./src/Composer/</directory>
            <exclude>
                <file>./src/Composer/Autoload/ClassLoader.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

参考资料: https://github.com/composer/composer/blob/master/tests/bootstrap.php

<?php

/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

error_reporting(E_ALL);

$loader = require __DIR__.'/../src/bootstrap.php';
$loader->add('Composer\Test', __DIR__);

上面的最后一行是在命名空间 Composer\Test 下自动加载 phpunit 测试类。


推荐