使用Composer和autoload.php自动加载PHPUnit中的类
我刚刚通过composer phpSebastian Bergmann安装了PHPUnit版本3.7.19,并且写了一个我想unit testing的类。
我希望将所有的类自动加载到每个unit testing中, 而不必使用include
或require
在我的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找不到类“返回”
我注意到composer
在vendor/autoload.php
生成了一个autoload.php
文件,但不知道这是否与我的问题有关。
此外,在Stack Overflow的其他一些答案中,人们提到了在composer中使用PSR-0和在PHP中使用namespace
命令,但是我没有成功地使用任何一种。
请帮忙! 我只想在PHPUnit中自动加载我的类,这样我就可以使用它们来创build对象,而不用担心include
或require
。
更新: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/"] } } }