Решение проблем пути с PHPUnit

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

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

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

4 ответов


поздний ответ, К сожалению.

Нет, ты ничего не теряешь. 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 поддерживает ваше глобальное состояние если вы используете глобальные (также суперглобальные) данные вообще, что может значительно замедлить ваши тесты, поэтому лучше избегать их после выполнения теста.


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

мне удалось выполнить требование установить $_SERVER ['DOCUMENT_ROOT'] для конфигурации задания Дженкинса. В "Bootstrap_test.РНР" выглядит как

<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 переменной, как правило, держат полный путь к каталогу заданий Дженкинса. Скажем, Дженкинса зовут 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 superglobal пуст, при вызове 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
}

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