[ACCEPTED]-Dealing with path issues with PHPUnit-include

Accepted answer
Score: 15

Late answer, sorry.

No, you're not missing 11 anything. PHP CLI (PHP for the Command Line) is 10 a different beast than PHP as an Apache 9 / CGI module.

What you could do, though is 8 change the setUp() of your files to set $_SERVER['DOCUMENT_ROOT'] to what 7 you need (since $_SERVER is still available as a 6 superglobal even in CLI context), e.g. :

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

Just 5 be careful, you probably want to put this 4 into your tearDown():

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

PHPUnit backs up your global state if you use global (also superglobal) data 3 at all, which can slow your tests down dramatically, hence 2 why it's better to avoid having any after 1 a test has run through.

Score: 7

Instead of injecting hacks into production 4 code or to test code, you can set up additional 3 variables directly in phpunit.xml (which you are going 2 to use at some point anyway) in php section:

<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>

Refer 1 to official documentation for other possible options

Score: 2

$_SERVER['DOCUMENT_ROOT'] can also be set in the Bootstrap file and 12 the same Bootstrap_test.php is attached to the phpunit configuration 11 file phpunit.xml with the attribute name bootstrap=Bootstrap_test.php

I was able 10 to achieve the requirement to set $_SERVER['DOCUMENT_ROOT'] for 9 Jenkins job configuration. The "Bootstrap_test.php" looks 8 like

<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>

and the contents in Bootstrap.php is declared using 7 define() function:

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

The BASE_PATH variable will typically hold 6 the full path to the Jenkins job directory. Say, Jenkins 5 job name is Test_Job. The directory where Jenkins 4 will place project source code is /var/lib/jenkins/jobs/Test_Job/workspace (assuming 3 jenkins work directory as /var/lib/jenkins).

If Bootstrap_test.php 2 is placed at the base directory, BASE_PATH will hold 1 /var/lib/jenkins/jobs/Test_Job/workspace and finally set to $_SERVER['DOCUMENT_ROOT'].

Score: 0

The best way would be to decouple your code 7 from the use of the $_SERVER or any other global 6 array. For example do

class MyClass
{
    protected $_docroot;

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

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

instead of

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

This allows 5 you to do

// 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();

Please be aware that this is just 4 a simple example of decoupling. It might 3 be much more complicated in your case - but 2 generally it's worth the effort, especially 1 if you'r running unit tests.

Score: 0

Just want to document calling another php files (like config.php) from 10 inside PHPUnit tests.
I have a test class:

class xyzTest extends TestCase {

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

...

In 9 config.php I set up some constants, like file paths. These 8 paths are relative to $_SERVER['DOCUMENT_ROOT'].
I want to test my 7 xyz class using these path constants.
However, the 6 $_SERVER superglobal is empty, when calling PHPUnit 5 from command line. I tried following the 4 good advice from an answer above and set the $_SERVER['DOCUMENT_ROOT'] in PHPUnits 3 setUp methods. This did not fix my issue.

I 2 fixed it by adding an if statement into my 1 Config.php, like so:

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

Hope this saves someone headache.

More Related questions