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

我刚刚通过composer phpSebastian Bergmann安装了PHPUnit版本3.7.19,并且写了一个我想unit testing的类。

我希望将所有的类自动加载到每个unit testing中, 不必使用includerequire在我的testing顶部,但是这certificate是困难的!

这是我的目录结构看起来像(后/斜线表示一个目录,而不是文件):

  • composer.json
  • composer.lock
  • composer.phar
  • LIB /
    • returning.php
  • testing/
    • returningTest.php
  • 供应商/
    • 斌/
      • PHPUnit的
    • composer php/
    • PHPUnit的/
    • symfony的/
    • autoload.php

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

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

我的returning.php类文件包含以下内容:

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

我的returningTest.phptesting文件包括以下内容:

 <?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找不到类“返回”

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

此外,在Stack Overflow的其他一些答案中,人们提到了在composer中使用PSR-0和在PHP中使用namespace命令,但是我没有成功地使用任何一种。

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


更新:2013年8月14日

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

那么,一开始呢 你需要告诉自动加载器在哪里find一个类的PHP文件。 这是通过遵循PSR-0标准完成的。

最好的方法是使用名称空间。 当您请求Acme\Tests\ReturningTest类时,自动加载器searchAcme/Tests/ReturningTest.php文件。 有一些伟大的命名空间教程在那里,只是search和阅读。 请注意,名称空间并不是用于自动加载的PHP,它可以用于自动加载。

Composer带有一个标准的PSR-0自动加载器( vendor/autoload.php )。 在你的情况下,你想告诉自动加载器searchlib目录中的文件。 那么当你使用ReturningTest它会查找/lib/ReturningTest.php

添加到你的composer.json

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

文档中的更多信息。

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

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

但是,使用PHPunitconfiguration文件更好:

 <!-- /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> 

现在,您可以运行命令,它会自动检测configuration文件:

 $ ./vendor/bin/phpunit 

如果将configuration文件放到另一个目录中,则需要使用-c选项将该目录的path放在该命令中。

[ Update2 ]另一个更简单的替代方法是在composer.json ( reference )中使用autoload-dev指令。 好处是你不需要维护两个bootstrap.php(一个是prod,一个是dev),只是为了自动加载不同的类。

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

[ 更新 ] Wouter J的答案更完整。 但是我可以帮助那些想要在tests/文件夹中设置PSR-0自动加载的人。
Phpunit使用这种模式扫描所有文件*Test.php 。 所以我们不需要自己自动加载它们。 但是我们仍然想自动加载tests/下的其他支持类,比如fixture / stub或者一些父类。

一个简单的方法就是看一下Composer项目本身是如何设置phpunittesting的。 其实很简单 注意“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下的phpunittesting类。

这些答案都不是我正在寻找的。 是PHPUnit加载testing文件,但不是存根/夹具。 Chaun Ma的回答并不能解决这个问题,因为运行vendor/bin/phpunit已经包含了autoload,所以没办法让自动加载器的一个实例把更多的path推送到堆栈上。

我最终在文档中find了这个:

如果您需要在多个目录中search相同的前缀,则可以将它们指定为一个数组,如下所示:

 { "autoload": { "psr-0": { "Monolog\\": ["src/", "lib/"] } } }