我刚刚通过 Composer 安装了 Sebastian Bergmann 的 PHPUnit 3.7.19 版,并编写了一个我想进行单元测试的类。
我希望将我的所有类自动加载到每个单元测试中而无需在我的测试顶部使用 include
或 require
,但事实证明这很困难!
这是我的目录结构的样子(尾部 / 斜杠表示目录,而不是文件):
* 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;
}
}
?>
我的 returnedTest.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 中找不到类“返回”
我注意到 composer
在 vendor/autoload.php
中生成了一个 autoload.php
文件,但不确定这是否与我的问题有关。
此外,在 Stack Overflow 上的其他一些答案中,人们提到了一些关于在 composer 中使用 PSR-0 和在 PHP 中使用 namespace
命令的内容,但我没有成功使用任何一个。
请帮忙!我只想在 PHPUnit 中自动加载我的类,这样我就可以使用它们来创建对象,而不必担心 include
或 require
。
更新:2013 年 8 月 14 日
我现在创建了一个名为 PHPUnit Skeleton 的开源项目,以帮助您轻松地为您的项目启动和运行 PHPUnit 测试。
嗯,一开始。您需要告诉自动加载器在哪里可以找到类的 php 文件。这是通过遵循 PSR-0 标准来完成的。
最好的方法是使用命名空间。当您请求 Acme\Tests\ReturningTest
类时,自动加载器会搜索 Acme/Tests/ReturningTest.php
文件。那里有一些很棒的命名空间教程,只需搜索和阅读。请注意,命名空间不是进入 PHP 用于自动加载的东西,它是可用于自动加载的东西。
Composer 带有一个标准的 PSR-0 自动加载器(vendor/autoload.php
中的那个)。在您的情况下,您想告诉自动加载器在 lib
目录中搜索文件。然后,当您使用 ReturningTest
时,它会查找 /lib/ReturningTest.php
。
将此添加到您的 composer.json
:
{
...
"autoload": {
"psr-0": { "": "lib/" }
}
}
the documentation 中的更多信息。
现在自动加载器可以找到你需要的类,让 PHPunit 在运行测试之前知道有一个文件要执行:一个引导文件。您可以使用 --bootstrap
选项指定引导文件的位置:
$ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php
但是,使用 PHPunit configuration file 会更好:
<!-- /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
选项将该目录的路径放入。
[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 项目本身是如何设置 phpunit 测试的。其实很简单。请注意带有“引导程序”的行。
参考: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 测试类。
composer dump-autoload --optimize
。这将重新生成需要包含在项目中的所有类的列表。
这些答案都不是我想要的。是的 PHPUnit 加载测试文件,但不加载存根/固定装置。 Chaun Ma 的回答并没有削减它,因为运行 vendor/bin/phpunit
已经包含自动加载,所以没有办法让自动加载器的实例在那时将更多路径推送到它的堆栈。
我最终在文档中找到了这个:
如果需要在多个目录中搜索相同的前缀,可以将它们指定为数组,如下所示: { "autoload": { "psr-0": { "Monolog\\": ["src/", "lib /"] } } }
vendor\bin\phpunit
已经 require
composer 的自动加载器类,它也不会阻止您再次require
它并获取 $loader
对象来添加新类。
有一种非常简单的方法可以设置 phpunit 并自动加载和引导。使用 phpunit 的 --generate-configuration
选项在几秒钟内创建您的 phpunit.xml
配置-:
vendor/bin/phpunit --generate-configuration
(或者如果您的 PATH 中设置了 phpunit,则只需 phpunit --generate-configuration
)。此选项已从 phpunit5 及更高版本中可用。
此选项将提示您输入引导文件 (vendor/autoload.php)、测试和源目录。如果您的项目使用 composer 默认设置(请参见下面的目录结构),则默认选项将是您所需要的。只需按三下 RETURN!
project-dir
-- src
-- tests
-- vendor
你会得到一个默认的 phpunit.xml,这很好。您当然可以进行编辑以包含您需要的任何专业(例如 colors="true"
):
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.1/phpunit.xsd"
bootstrap="vendor/autoload.php"
executionOrder="depends,defects"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
verbose="true">
<testsuites>
<testsuite name="default">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
如果您使用 PHPUnit 7,您可以让 src/
文件夹中的类在测试中自动加载,如下所示:
确保您的 composer.json 文件看起来类似于: { "autoload": { "classmap": [ "src/" ] }, "require-dev": { "phpunit/phpunit": "^7" } }在 composer.json 运行命令中应用更改: composer install 最后,您可以在 tests/ 文件夹中运行测试: ./vendor/bin/phpunit tests/
不定期副业成功案例分享
PHP Fatal error: Class 'Returning' not found in /files/code/php/db/tests/returningTest.php on line 8
。我如何找出我做错了什么?<phpunit bootstrap="./vendor/autoload.php">
只为“lib/”下的类设置自动加载器。您仍然需要在“tests/”下自动加载类。tests/
目录并运行测试类,那里已经自动加载了。phpunit.xml
文件中没有bootstrap="./vendor/autoload.php"
。现在它自动加载正常!谢谢!