Решение проблем с путями с PHPUnit - PullRequest
11 голосов
/ 31 октября 2009

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

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

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

Ответы [ 5 ]

13 голосов
/ 21 апреля 2010

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

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

2 голосов
/ 03 октября 2013

$_SERVER['DOCUMENT_ROOT'] также можно установить в файле Bootstrap, и тот же 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. Каталог, в который Jenkins поместит исходный код проекта, - /var/lib/jenkins/jobs/Test_Job/workspace (при условии, что рабочий каталог jenkins - /var/lib/jenkins).

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

1 голос
/ 28 октября 2018

Вместо внедрения хаков в производственный код или для тестирования кода вы можете установить дополнительные переменные непосредственно в 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>

См. официальную документацию для других возможных вариантов

0 голосов
/ 05 марта 2018

Просто хочу документировать вызов других 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
}

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

0 голосов
/ 31 октября 2009

Лучшим способом было бы отделить ваш код от использования $_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();

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...