phpunit testsuite independent

时间:2011-01-13 10:59:05

标签: php phpunit cruisecontrol

我在phpunit中运行一系列测试,这些测试存在于单独的测试套件中,其列表由phpunit配置文件控制。当测试单独运行时(即不通过配置文件运行,因此一次运行测试套件)它们通过但是,当一起运行时,我会失败。

仔细检查问题是这些测试套件中的每一个都是在框架中加载(通过require_once),并且该框架根据require_once时的设置执行一些内部配置。看来,在运行phpunit配置文件中单独列出的测试套件之间,各种各样的事情仍然存在。在这种特殊情况下,框架已被视为已加载。

所以 - 是否有办法让phpunit独立执行一系列测试套件,即等同于一次一个地在测试套件上运行phpunit?(phpunit由autotest上的cruisecontrol触发机器人和本地开发人员在提交之前。)我已经尝试了诸如'--process-isolation'和'--no-globals-backup'之类的选项而没有成功。

说明问题的一个简单例子是'constant.php'文件:

<?php
if (defined('XYZZY')) define('TEST', 1);
else define('TEST', 2);

testuite'TestOne.php':

<?php
define('XYZZY', "");
require_once('constant.php');
class TestOne extends PHPUnit_Framework_TestCase
{
   public function testOne()
   {
      $this->assertEquals(TEST, 1);
   }
}

类似的测试套件'TestTwo.php':

<?php
require_once('constant.php');
class TestTwo extends PHPUnit_Framework_TestCase
{
   public function testTwo()
   {
      $this->assertEquals(TEST, 2);
   }
}

和phpunit配置文件:

<phpunit>
  <testsuites>
    <testsuite name="First">
      <file>./TestOne.php</file>
    </testsuite>

    <testsuite name="Second">
      <file>./TestTwo.php</file>
    </testsuite>
  </testsuites>
</phpunit>

2 个答案:

答案 0 :(得分:1)

我试图为您提供一些工作示例--process-isolation而不是全局备份。

希望您能够让您的测试与这些一起工作。如果不是给我留言,我会看到回复你。

我已经用3.4.15测试了大部分内容,并且所有针对HEAD的测试(3.5.x预计也会起作用)

最简单的方法是:

<?php
class Test extends PHPUnit_Framework_TestCase
{
    public function testOne()
    {
        define('FOO', 'BAR');
        $this->assertEquals('BAR', FOO);
    }

    public function testTwo()
    {
        define('FOO', 'BAZ');
        $this->assertEquals('BAZ', FOO);
    }
}

并产生:

  

phpunit --process-isolation processTest.php

     

Sebastian Bergmann的PHPUnit @ package_version @。

     

...

     

时间:0秒,内存:1.25Mb

     

好(2次测试,2次断言)

因此,如果你在测试套件中对测试进行分组,或者你可以为每个测试用例运行设置(取决于它的价格有多大),你可以使用简单的方法:

<?php
class Test extends PHPUnit_Framework_TestCase
{
    public function setUp() 
    {
        // your bootstrap for testsuite X
        // Maybe put this in a baseclass for that suite ?
    }

    public function testOne()
    {
        $this->assertEquals('BAR', FOO);
    }

简而言之

确保在进入测试(和过程隔离)后运行设置代码

如果其他一切都失败了,你/我们无法解决这个问题:

使用runkit扩展名(即使是NEAR制作也不安全,可作为最后手段使用),您可以调用runkit-constant-remove()等函数


希望这有助于实现。如果没有:让我知道

答案 1 :(得分:0)

我遇到了类似的问题,遇到了一种不同的方式,这个问题在最初被问到这个问题时可能还没有。

在我的情况下,我必须测试一些检查全局常量的遗留代码,并在设置时执行某个操作。这很容易,但在一次测试中define常量后,它会持续通过剩余的测试。要更改此行为,PHPUnit会提供@runInSeparateProcess@preserveGlobalState注释。

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */
public function test_presence_of_constant() {
  define('SOME_OVERRIDE', 'true');
  $result = $this->target->legacyMethod();
  $this->assertEquals('thereWasSomeOverride', $result);
}

如果只有少数测试需要单独运行,那么这种方法很有效。