2009-10-31 110 views
10

我刚开始使用PHPUnit,但遇到了一些问题。我的代码使用$ _SERVER ['DOCUMENT_ROOT']来计算includes的路径,当我的apache服务器是运行PHP的服务器时工作,但是当我使用“phpunit测试”从命令行运行phpunit时没有设置DOCUMENT_ROOT。 ,所以这些包括不起作用。处理PHPUnit的路径问题

我错过PHPUnit的配置中的东西吗?它应该以某种方式与Apache整合?

回答

14

最后回答,对不起。

不,你不会错过任何东西。 PHP CLI(用于命令行的PHP)与Apache/CGI模块不同,它与PHP不同。

你可以做什么,不过是将文件的setUp()更改为$_SERVER['DOCUMENT_ROOT']以满足您的需求(因为$_SERVER即使在CLI环境下仍然可以作为超全球使用),例如, :

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

只是要小心,你可能希望把这个变成你的tearDown()

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

PHPUnit backs up your global state如果你使用全局(也超全局)的任何数据,从而大大减缓你的测试下来,因此为什么在测试结束后避免有任何问题会更好。

0

最好的办法是从使用$_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(); 

请注意,这是脱钩的只是一个简单的例子。在你的情况下它可能要复杂得多 - 但通常这是值得的,特别是如果你正在运行单元测试。

+0

问题就变成了,我如何包含包含这个类的文件? – 2009-10-31 10:39:16

+0

好的 - 我看到了问题......我稍微误解了你的问题的真实背景。你不应该依赖包含任何环境变量的文件(包括'$ _SERVER ['DOCUMENT_ROOT']')。您是否有可能使用相对路径包含文件,例如'require_once dirname(__ FILE__)。 “/ MyClass.php''?另一方面,您可以设置某种自动加载... – 2009-10-31 10:52:51

1

$_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变量通常会保持完整路径詹金斯作业目录。说,詹金斯的工作名称是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']

0

只是想要从PHPUnit测试中调用另一个php文件(如config.php)
我有一个测试类:

class xyzTest extends TestCase { 

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

... 

config.php我设置了一些常量,比如文件路径。这些路径相对于$_SERVER['DOCUMENT_ROOT']
我想用这些路径常数测试我的xyz类。
但是,当从命令行调用PHPUnit时,超全局变量$_SERVER为空。我尝试遵循answer above的好建议,并在PHPUnits setUp方法中设置$_SERVER['DOCUMENT_ROOT']。这并没有解决我的问题。

我固定它通过添加if陈述了我的Config.php,像这样:

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

希望这可以节省有人头痛。