我刚刚开始使用PHPUnit,但我遇到了一些障碍。
我的代码使用$ _SERVER ['DOCUMENT_ROOT']来计算包含的路径,当我的apache服务器是运行PHP的服务器时,它运行,但是当我从命令行运行带有“phpunit Tests”的phpunit时,没有设置DOCUMENT_ROOT,所以这些包括不起作用。
我在PHPUnit的配置中遗漏了什么?它应该以某种方式与apache集成吗?
答案 0 :(得分:13)
迟到的回答,抱歉。
不,你没有遗漏任何东西。 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 backs up your global state如果您使用全局(也包括超全局)数据,这会大大减慢您的测试速度,因此为什么在测试完成后避免任何测试更好。
答案 1 :(得分: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']
。
答案 2 :(得分:1)
您可以在phpunit.xml
部分的php
中直接设置其他变量,而不是在生产代码或测试代码中添加hacks:>
<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>
有关其他可能的选项,请参考official documentation
答案 3 :(得分: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();
请注意,这只是解耦的一个简单示例。在你的情况下可能会复杂得多 - 但通常值得付出努力,特别是如果你正在进行单元测试。
答案 4 :(得分: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 $_SERVER['DOCUMENT_ROOT']
方法中设置setUp
。这并没有解决我的问题。
我通过在if
中添加Config.php
语句来修复它,如下所示:
if ($_SERVER['DOCUMENT_ROOT']) {
$DocumentRoot = realpath($_SERVER['DOCUMENT_ROOT']);
} else {
$DocumentRoot = realpath(dirname(__FILE__) . '/../..'); //for PHPUnit
}
希望这可以让别人头疼。