1

我打电话phpunit的参数是一个目录(额外的问题:为什么它不能接受文件列表?)现在它抱怨一个类被多次声明,因为前面的测试中包含一个文件!

如果我运行phpunit firstTest.php; phpunit secondTest.php一切正常

phpunit ./失败了PHP Fatal error: Cannot redeclare class X

我的测试基本上是:

include 'class_to_be_tested.php'
class class1Test extends...

没有别的了。我正在使用该选项--process-isolation。我可以添加require_once 我的课程,但这不是我希望能够单独测试它们的内容。

phpunit 不应该遵循最佳测试实践并运行一个测试,清除它所拥有的任何垃圾,在干净状态下运行另一个测试吗?还是我做错了什么?

4

3 回答 3

2

由于您的include问题include_once中没有显示其他代码,因此无法重新声明错误也可能是您在被测代码的某个位置再次包含该文件。

假设情况并非如此,那么在幕后发生的一些事情--process-isolation可以保留全局类声明。这篇博文提供了更多细节: http: //matthewturland.com/2010/08/19/process-isolation-in-phpunit/

基本上,您将需要创建自己的基础TestCase并覆盖将run()方法设置preserveGlobalStatefalse. 这应该正确地允许您的所有测试一起运行。

基类看起来与此类似(摘自我提到的博客文章):

class MyTestCase extends PHPUnit_Framework_TestCase
{
    public function run(PHPUnit_Framework_TestResult $result = NULL)
    {
       $this->setPreserveGlobalState(false);
       return parent::run($result);
    }
}
于 2013-03-14T21:08:47.093 回答
1

改变:

include 'class_to_be_tested.php';
class class1Test extends...

成为:

include_once 'class_to_be_tested.php';
class class1Test extends...

在 PHP 中,您需要有一个非常好的理由才能使用前者。

关于为什么它不能接受文件列表?,我认为设计决定是您通常不需要。但是,您可以通过在 phpunit.xml.dist 文件中创建一个测试套件来做到这一点,请参阅 http://www.phpunit.de/manual/current/en/organizing-tests.html#organizing-tests.xml-configuration

于 2013-03-15T12:38:26.250 回答
1

phpUnit 的工作方式意味着您的所有测试都在单个 php 程序的上下文中运行。phpUnit 旨在将测试彼此隔离,但它们都在同一个程序执行中运行。

PHP 的include语句将包含所请求的文件,而不管它之前是否被包含过。这意味着,如果你include给定的课程两次,第二次你会得到一个错误。这发生在您的测试中,因为每个测试都包含相同的文件,但没有考虑它是否已被其他测试之一包含。

解决方案:

  • 用 a包装您的include调用,if(class_exists('classname'))以便在已定义类的情况下不包含该文件。

  • 将文件包含在 phpUnit 引导文件中,而不是包含在测试中。

  • 使用include_once(甚至require_once)代替include.

  • 停止任意包含文件,并开始使用自动加载器。

于 2013-03-15T12:51:24.303 回答