Подтвердить что ты не робот

Автозагрузка классов в PHPUnit с использованием Composer и autoload.php

Я только что установил PHPUnit версии 3.7.19 от Себастьяна Бергмана через Composer и написал класс, который я хотел бы unit test.

Я хотел бы, чтобы все мои классы автоматически загружались в каждый unit test без, чтобы использовать include или require в верхней части моего теста, но это сложно!

Это то, что выглядит моя структура каталогов (трейлинг/слэш указывает каталог, а не файл):

  • composer.json
  • composer.lock
  • composer.phar
  • Библиотека /
    • returning.php
  • Тесты /
    • returningTest.php
  • продавец /
    • бен /
      • PHPUnit
    • композитор /
    • 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 для вашего проекта.

4b9b3361

Ответ 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 для автоматической загрузки в тестах следующим образом:

  1. Убедитесь, что ваш файл composer.json выглядит примерно так:

    {
        "autoload": {
            "classmap": [
                "src/"
            ]
        },
        "require-dev": {
            "phpunit/phpunit": "^7"
        }
    }
    
  2. Чтобы применить изменения в команде composer.json run:

    composer install
    
  3. Наконец, вы можете запускать тесты в 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>