Автозагрузка классов в PHPUnit с использованием Composer и autoload.php
Я только что установил PHPUnit версии 3.7.19 от Себастьяна Бергмана через Composer и написал класс, который я хотел бы unit test.
Я хотел бы, чтобы все мои классы автоматически загружались в каждый unit test без, чтобы использовать include
или require
в верхней части моего теста, но это сложно!
Это то, что выглядит моя структура каталогов (трейлинг/слэш указывает каталог, а не файл):
- composer.json
- composer.lock
- composer.phar
- Библиотека /
- Тесты /
- продавец /
- бен /
- композитор /
- PHPUnit/
- Symfony/
- autoload.php
Мой файл composer.json содержит следующее:
"require": {
"phpunit/phpunit": "3.7.*",
"phpunit/phpunit-selenium": ">=1.2"
}
В файле класса return.php содержится следующее:
<?php
class Returning {
public $var;
function __construct(){
$this->var = 1;
}
}
?>
Мой тестовый файл returnTest.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 Неустранимая ошибка: класс "Возврат" не найден в /files/code/php/db/tests/returningTest.php в строке 8
Я заметил, что composer
создал файл autoload.php
в vendor/autoload.php
, но не уверен, что это актуально для моей проблемы.
Кроме того, в некоторых других ответах на Qaru люди упоминали что-то об использовании PSR-0 в композиторе и команду namespace
в PHP, но у меня нет было успешным в использовании одного из них.
Пожалуйста, помогите! Я просто хочу автозагружать свои классы в PHPUnit, поэтому я могу просто использовать их для создания объектов, не беспокоясь о include
или require
.
Обновление: 14 августа 2013
Теперь я создал проект с открытым исходным кодом под названием PHPUnit Skeleton, чтобы помочь вам быстро и легко протестировать PHPUnit для вашего проекта.
Ответы
Ответ 1
Хорошо, сначала. Вы должны указать автозагрузчику, где найти файл php для класса. Это сделано, следуя стандарту PSR-0.
Лучший способ - использовать пространства имен. Автозагрузчик выполняет поиск файла Acme/Tests/ReturningTest.php
при запросе класса Acme\Tests\ReturningTest
. Там есть несколько замечательных учебников по пространству имен, просто поиск и чтение. Обратите внимание, что пространство имен не входит в PHP для автозагрузки, это то, что можно использовать для автозагрузки.
Композитор поставляется со стандартным автозагрузчиком PSR-0 (один в vendor/autoload.php
). В вашем случае вы хотите сказать автозагрузчику поиск файлов в каталоге lib
. Затем, когда вы используете ReturningTest
, он будет искать /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 test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
Теперь вы можете запустить команду, и она автоматически определит файл конфигурации:
$ ./vendor/bin/phpunit
Если вы поместите файл конфигурации в другой каталог, вам нужно указать путь к этому каталогу в команде с опцией -c
.
Ответ 2
[ Update2] Другим более простым альтернативным подходом является использование директивы autoload-dev
в composer.json
(ссылка). Преимущество в том, что вам не нужно поддерживать два bootstrap.php(один для prod, один для dev) только для того, чтобы автозагружать разные классы.
{
"autoload": {
"psr-4": { "MyLibrary\\": "src/" }
},
"autoload-dev": {
"psr-4": { "MyLibrary\\Tests\\": "tests/" }
}
}
[ Обновить] Ответ Wouter J более полный. Но мой может помочь людям, которые хотят настроить автозагрузку PSR-0 в папке tests/
.
Phpunit сканирует все файлы с помощью этого шаблона *Test.php
. Поэтому нам не нужно самостоятельно загружать их. Но мы по-прежнему хотим автозагружать другие вспомогательные классы в tests/
, такие как fixture/stub или некоторые родительские классы.
Легкий способ - посмотреть, как сам проект 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 <[email protected]>
* Jordi Boggiano <[email protected]>
*
* 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__);
Последняя строка выше - автозагрузка тестовых классов phpunit в пространстве имен Composer\Test.
Ответ 3
Ни один из этих ответов не был тем, что я искал. Да PHPUnit загружает тестовые файлы, но не заглушки/приборы. Ответ Chaun Ma не сокращает его, потому что запуск vendor/bin/phpunit
уже включает автозагрузку, поэтому нет способа получить экземпляр автозагрузчика, чтобы направить в него больше стеков.
В конце концов я нашел это в документах:
Если вам нужно найти один и тот же префикс в нескольких каталогах, вы могут указывать их как массив как таковой:
{
"autoload": {
"psr-0": { "Monolog\\": ["src/", "lib/"] }
}
}
Ответ 4
Если вы используете PHPUnit 7, вы можете сделать свои классы из src/
folder для автоматической загрузки в тестах следующим образом:
-
Убедитесь, что ваш файл composer.json
выглядит примерно так:
{
"autoload": {
"classmap": [
"src/"
]
},
"require-dev": {
"phpunit/phpunit": "^7"
}
}
-
Чтобы применить изменения в команде composer.json
run:
composer install
-
Наконец, вы можете запускать тесты в tests/
папке:
./vendor/bin/phpunit tests/
Ответ 5
Есть действительно простой способ настроить phpunit с автозагрузкой и загрузкой. Используйте параметр phpunit --generate-configuration
чтобы за несколько секунд создать конфигурацию phpunit.xml
:
vendor/bin/phpunit --generate-configuration
(Или просто phpunit --generate-configuration
если phpunit установлен в вашем PATH). Эта опция была доступна с phpunit5.
Эта опция запросит у вас файл начальной загрузки (vendor/autoload.php), тесты и исходные каталоги. Если ваш проект настроен с настройками композитора по умолчанию (см. Ниже структуру каталогов), вам по умолчанию будут доступны опции по умолчанию. Просто нажмите RETURN три раза!
project-dir
-- src
-- tests
-- vendor
Вы получаете phpunit.xml по умолчанию, и это хорошо. Вы, конечно, можете редактировать, чтобы включить любые специализации (например, colors="true"
), которые вы require-:
<?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>