使用 PHPUnit 处理路径问题

问题描述 投票:0回答:5

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

我的代码使用

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

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

php unit-testing testing phpunit include
5个回答
16
投票

回复晚了,抱歉。

不,你没有错过任何东西。 PHP CLI(PHP 命令行)与作为 Apache / CGI 模块的 PHP 不同。

不过,您可以做的是更改文件的

setUp()
,将
$_SERVER['DOCUMENT_ROOT']
设置为您需要的内容(因为即使在 CLI 上下文中,
$_SERVER
仍然可以作为超全局使用),例如:

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

请小心,您可能想将其放入您的

tearDown()

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

如果您使用全局(也是超全局)数据,PHPUnit 会备份您的全局状态,这会显着减慢您的测试速度,因此为什么最好在测试运行后避免使用任何数据。


7
投票
您可以直接在

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>

请参阅

官方文档了解其他可能的选项


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 作业目录的完整路径。比如说,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']


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
投票
只想记录

从 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 的好建议,并在 PHPUnits $_SERVER['DOCUMENT_ROOT']
 方法中设置 
setUp
。这并没有解决我的问题。 

我通过在我的

if

 中添加 
Config.php
 语句来修复它,如下所示:

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

希望这能减轻一些人的头痛。

© www.soinside.com 2019 - 2024. All rights reserved.