it-roy-ru.com

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

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

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

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

  • composer.json
  • composer.lock
  • composer.phar
  • lib /
    • returning.php
  • тесты /
    • returningTest.php
  • продавец /
    • бен /
      • pHPUnit
    • композитор/
    • 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.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: класс 'Returning' не найден в /files/code/php/db/tests/returningTest.php в строке 8

Я заметил, что composer создал autoload.php файл в vendor/autoload.php, но не уверен, относится ли это к моей проблеме.

Кроме того, в некоторых других ответах о переполнении стека люди упоминали что-то об использовании PSR- в composer и ​​команде namespace в PHP, но мне не удалось использовать ни одну из них ,.

Пожалуйста помоги! Я просто хочу автоматически загружать свои классы в PHPUnit, чтобы я мог просто использовать их для создания объектов, не беспокоясь о include или require.


Обновление: 14 августа 2013 г.

Теперь я создал проект с открытым исходным кодом под названием PHPUnit Skeleton , чтобы помочь вам легко приступить к тестированию PHPUnit для вашего проекта.

60
Jasdeep Khalsa

Ну, во-первых. Вы должны указать автозагрузчику, где найти php-файл для класса. Это сделано, следуя стандарту PSR-0.

Лучший способ - использовать пространства имен. Автозагрузчик ищет файл Acme/Tests/ReturningTest.php, когда вы запросили класс Acme\Tests\ReturningTest. Есть несколько хороших учебников по пространству имен, просто ищите и читайте. Обратите внимание, что пространство имен это not что-то, что вошло в PHP для автозагрузки, это то, что можно использовать для автозагрузки.

Composer поставляется со стандартным автозагрузчиком 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's test suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>

</phpunit>

Теперь вы можете запустить команду, и она автоматически обнаружит файл конфигурации:

$ ./vendor/bin/phpunit

Если вы поместили файл конфигурации в другой каталог, вам нужно указать путь к этому каталогу в команде с параметром -c.

70
Wouter J

[Update2] Другой более простой альтернативный подход заключается в использовании директивы autoload-dev в composer.json ( reference ). Преимущество заключается в том, что вам не нужно поддерживать два файла 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. Это на самом деле очень просто. Обратите внимание на строку с «начальной загрузкой».

ссылка: 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.

40
Chuan Ma

Ни один из этих ответов не был тем, что я искал. Да, PHPUnit загружает тестовые файлы, но не заглушки/исправления. Ответ Чауна Ма не обрезает его, потому что запуск vendor/bin/phpunit уже включает автозагрузку, поэтому нет способа получить экземпляр автозагрузчика, чтобы протолкнуть больше путей к его стеку в этот момент.

В конце концов я нашел это в документах:

Если вам нужно искать один и тот же префикс в нескольких каталогах, вы можно указать их как массив как таковой:

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

Существует действительно простой способ настройки 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"), которые вам требуются:

<?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>
1
suspectus

Если вы используете PHPUnit 7 вы можете сделать свои классы из папки src/ для автоматической загрузки в таких тестах:

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

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

    composer install
    
  3. Наконец, вы можете запустить тесты в папке tests/:

    ./vendor/bin/phpunit tests/
    
0
yesnik