14

我刚刚开始使用 PHPUnit,但遇到了一些障碍。

我的代码使用 $_SERVER['DOCUMENT_ROOT'] 来计算包含的路径,当我的 apache 服务器是运行 PHP 的服务器时有效,但是当我使用“phpunit Tests”从命令行运行 phpunit 时未设置 DOCUMENT_ROOT,因此这些包括不工作。

我在 PHPUnit 的配置中遗漏了什么吗?它应该以某种方式与apache集成吗?

4

5 回答 5

15

迟到的答案,对不起。

不,你没有错过任何东西。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 会备份您的全局状态,这会大大减慢您的测试速度,因此最好避免在测试运行后有任何状态。

于 2010-04-21T14:15:21.520 回答
6

无需将 hack 注入生产代码或测试代码,您可以直接在以下部分中设置其他变量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>

有关其他可能的选项,请参阅官方文档

于 2018-10-28T16:04:55.063 回答
2

$_SERVER['DOCUMENT_ROOT']也可以在Bootstrap文件中设置,同样Bootstrap_test.php附在phpunit配置文件phpunit.xml中,属性名bootstrap=Bootstrap_test.php

我能够实现为 Jenkins 作业配置设置 $_SERVER['DOCUMENT_ROOT'] 的要求。“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'].

于 2013-10-03T09:19:38.840 回答
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();

请注意,这只是一个简单的解耦示例。在您的情况下它可能要复杂得多 - 但通常值得付出努力,特别是如果您正在运行单元测试。

于 2009-10-31T10:22:33.877 回答
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使用这些路径常量测试我的类。
但是,$_SERVER当从命令行调用 PHPUnit 时,超全局是空的。我尝试遵循上述答案中的好建议并设置$_SERVER['DOCUMENT_ROOT']PHPUnitssetUp方法。这并没有解决我的问题。

if我通过在 my 中添加一条语句来修复它Config.php,如下所示:

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

希望这可以避免一些人头疼。

于 2018-03-05T19:27:25.563 回答