Вопрос

Я только начал использовать PHPUnit, но столкнулся с небольшой загвоздкой.

Мой код использует $_SERVER['DOCUMENT_ROOT'] для вычисления путей для включений, что работает, когда на моем сервере apache запущен PHP, но DOCUMENT_ROOT не задан, когда я запускаю phpunit из командной строки с помощью "phpunit Tests", поэтому эти включения не работают.

Я что-то упускаю в конфигурации PHPUnit?Должен ли он каким-то образом быть интегрирован с apache?

Это было полезно?

Решение

Поздний ответ, извините.

Нет, ты ничего не упускаешь.PHP CLI (PHP для командной строки) - это другой зверь, чем PHP как модуль Apache / CGI.

Однако что вы могли бы сделать, так это изменить setUp() из ваших файлов для установки $_SERVER['DOCUMENT_ROOT'] к тому, что вам нужно (поскольку $_SERVER по-прежнему доступен как суперглобальный даже в контексте CLI), например:

public function setUp() {
  $_SERVER['DOCUMENT_ROOT'] = dirname(__FILE__) . "/../application";
}

Просто будьте осторожны, вы, вероятно, захотите поместить это в свой tearDown():

public function tearDown() {
  unset($_SERVER['DOCUMENT_ROOT']);
}

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

Другие советы

Вместо внедрения взломов в производственный код или для тестирования кода вы можете настроить дополнительные переменные непосредственно в phpunit.xml (который вы все равно собираетесь использовать в какой-то момент) в php Раздел:

<phpunit bootstrap="vendor/autoload.php">

    <php>
        <server name="DOCUMENT_ROOT" value="wwwroot" />
        <server name="SERVER_NAME" value="localhost" />

        <const name="PHPUNIT_TESTSUITE" value="true"/>
    </php>
</phpunit>

Обратитесь к официальная документация для других возможных вариантов

$_SERVER['DOCUMENT_ROOT'] также может быть установлен в файле начальной загрузки и тот же Bootstrap_test.php прикреплен к файлу конфигурации phpunit phpunit.xml с именем атрибута bootstrap=Bootstrap_test.php

Мне удалось выполнить требование установить $_SERVER['DOCUMENT_ROOT'] для конфигурации задания Jenkins."Bootstrap_test.php" выглядит как

<phpunit

   backupGlobals="false"

   backupStaticAttributes="false"

   strict="true"

   verbose="true"

   bootstrap="Bootstrap_test.php">

   <testsuites>

     <testsuite name="PHPUnit Test Suite">

     <file>PHPUnitTest.php</file>

     </testsuite>

   </testsuites>

   <logging>

     <log type="coverage-clover" target="logs/clover.xml"/>

   </logging>

</phpunit>

и содержимое в Bootstrap.php объявляется с использованием define() функция:

define('BASE_PATH', realpath(dirname(__FILE__)));    
$_SERVER['DOCUMENT_ROOT'] = BASE_PATH;

В BASE_PATH переменная обычно содержит полный путь к каталогу заданий Jenkins.Скажем, Дженкинса зовут на работу Test_Job.Каталог, в который Дженкинс разместит исходный код проекта, находится /var/lib/jenkins/jobs/Test_Job/workspace (предполагая, что рабочий каталог дженкинса является /var/lib/jenkins).

Если Bootstrap_test.php помещается в базовый каталог, BASE_PATH будет держать /var/lib/jenkins/jobs/Test_Job/workspace и, наконец, приступили к $_SERVER['DOCUMENT_ROOT'].

Лучшим способом было бы отделить ваш код от использования $_SERVER или любой другой глобальный массив.Например, сделать

class MyClass
{
    protected $_docroot;

    public function __construct($docroot)
    {
        $this->_docroot = $docroot;
    }

    public function getDocRoot() 
    {
        return $this->_docroot;
    }
}

вместо того , чтобы

class MyClass
{
    public function getDocRoot() 
    {
        return $_SERVER['DOCUMENT_ROOT'];
    }
}

Это позволяет вам делать

// in your actual code
$instance = new MyClass($_SERVER['DOCUMENT_ROOT']);
$docroot = $instance->getDocRoot();

// in your test
$instance = new MyClass($variable_holding_the_correct_path);
$docroot = $instance->getDocRoot();

Пожалуйста, имейте в виду, что это всего лишь простой пример развязки.В вашем случае это может быть намного сложнее, но в целом это стоит затраченных усилий, особенно если вы запускаете модульные тесты.

Просто хочу задокументировать вызов других php-файлов (например config.php) из внутренних тестов PHPUnit.
У меня есть тестовый класс:

class xyzTest extends TestCase {

    public static function setUpBeforeClass() {
        require_once __DIR__ . '/../../app/config/Config.php';
    }

...

В config.php Я настроил некоторые константы, например пути к файлам.Эти пути относятся к $_SERVER['DOCUMENT_ROOT'].
Я хочу проверить свою xyz класс, использующий эти константы пути.
Однако, в $_SERVER суперглобальный файл пуст при вызове PHPUnit из командной строки.Я попытался последовать хорошему совету от ответ выше и установите $_SERVER['DOCUMENT_ROOT'] в PHPUnits setUp методы.Это не устранило мою проблему.

Я исправил это, добавив if заявление в мой Config.php, вот так:

if ($_SERVER['DOCUMENT_ROOT']) {
    $DocumentRoot = realpath($_SERVER['DOCUMENT_ROOT']);
} else {
    $DocumentRoot = realpath(dirname(__FILE__) . '/../..'); //for PHPUnit
}

Надеюсь, это избавит кого-нибудь от головной боли.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top