PHPUnit一次加载所有类。导致PHP致命错误:无法重新声明类

时间:2014-05-15 02:56:05

标签: php phpunit classloader fatal-error redeclare

我已经完成了尽职调查,但我认为到目前为止,任何问题都没有涉及到这个问题。

我的情况是我的PHP代码根据配置属性生成类定义。

类定义基本上是数据持有者,可以有:

  • 公共财产
  • 或具有提供getter / setter的公共接口的受保护属性。

在某些配置情况下,生成的CLASS NAMES将是相同的,但它们的文件名称将是不同的。在真实环境中,用户只需根据所需的配置生成一组类定义,并在其应用程序中使用这些类。即使用户生成多组类定义,也没有问题。 PHP会愉快地流失,只提供应用程序中引用的一组定义。

我有两个PHPUnit测试用例,其中我使用具有由config生成的不同定义的类进行基本相同的测试。我使用" require_once"在我的所有代码中,并在单元测试中执行相同的操作," require_once"仅使用我测试所需的类文件。

PHPUnit配置为运行它在我的测试目录下找到并正常运行的所有测试。当我为不同的类生成添加测试时,PHPUnit停止使用PHP致命错误:无法重新声明类。

现在,PHPUnit的默认行为似乎是加载所有测试需要一次运行的所有类。这甚至在运行任何测试之前都会导致致命的PHP错误,因为PHPUnit为生成的类选择了第二个定义(它们具有相同的类名但文件名不同),即使我只有" require_once" ed在每个测试文件中更正正确的类定义。

我仍然可以运行测试,但一次只能使用一个测试文件,因此目前我必须运行所有测试 手动或批处理文件。不可能在所有测试中提供完整的代码覆盖率报告。

我想要的行为是PHPUnit只加载每个测试文件已被" require_once" ed的类,而不是它看到从phpunit.xml配置运行的所有测试文件。或者更好的方法是让PHPUnit只为指定的所有测试加载自己的类,并让PHP本身为每个测试做用户" require_once"

有没有办法解决这个问题?我看过PHPUnit配置设置,但似乎没有适合特定问题。我并不熟悉PHPUnit,因此构建另一个测试套件很困难。

最好做一个简单的例子。这里有几个PHPUnit测试文件foo1Test.php和foo2test.php。唯一的 它们之间的区别在于它们需要一个不同的类文件,它具有Foo类的定义。这没关系 所有这些类都是空的,它们都是完全合法的,它很好地证明了这个问题。我把所有这些都放了 ' testfoo'中的文件目录并在它们上运行PHPunit。你也可以这样做,你会得到相同的结果。

foo1Test.php

<?php

require_once dirname ( __FILE__ ).'/Foo1.php';

class Foo1TestCase extends PHPUnit_Framework_TestCase
{
}

?>

foo2Test.php

<?php

require_once dirname ( __FILE__ ).'/Foo2.php';

class Foo2TestCase extends PHPUnit_Framework_TestCase
{
}

?>

Foo1.php

<?php

class Foo
{
}

?>

Foo2.php

<?php

class Foo
{
}

?>

两个测试文件foo1Test.php和foo2Test.php是完全有效的文件,并通过以下PHPunit命令行运行

phpunit foo1Test.php
phpunit foo2Test.php

正如您所料,PHPUnit没有抱怨任何测试没问题。

我还有一个标准的phpunit.xml配置文件,它将运行当前目录下的所有测试。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupStaticAttributes="false"
         cacheTokens="false"
         colors="false"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         forceCoversAnnotation="false"
         mapTestClassNameToCoveredClassName="false"
         printerClass="PHPUnit_TextUI_ResultPrinter"
         processIsolation="false"
         stopOnError="false"
         stopOnFailure="false"
         stopOnIncomplete="false"
         stopOnSkipped="false"
         testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
         strict="false"
         verbose="true">
    <testsuite name="fooTests">
        <directory>.</directory>
    </testsuite>
</phpunit>

我使用此配置运行PHPUnit,如下所示

PHPUnit的

输出结果为:

PHP Fatal error:  Cannot redeclare class Foo in /var/www/testfoo/Foo2.php on line 4
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP   3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:130
PHP   4. PHPUnit_TextUI_Command->handleArguments() /usr/share/php/PHPUnit/TextUI/Command.php:139
PHP   5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() /usr/share/php/PHPUnit/TextUI/Command.php:671
PHP   6. PHPUnit_Util_Configuration->getTestSuite() /usr/share/php/PHPUnit/Util/Configuration.php:768
PHP   7. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/php/PHPUnit/Util/Configuration.php:848
PHP   8. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/php/PHPUnit/Framework/TestSuite.php:419
PHP   9. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/php/PHPUnit/Framework/TestSuite.php:358
PHP  10. PHPUnit_Util_Fileloader::load() /usr/share/php/PHPUnit/Util/Fileloader.php:79
PHP  11. include_once() /usr/share/php/PHPUnit/Util/Fileloader.php:95
PHP  12. require_once() /var/www/testfoo/foo2Test.php:3

这就是这个问题的内容。虽然测试文件完全有效,但PHPUnit不会在测试套件下运行测试,因为它在运行任何测试之前都试图加载整个测试套件所需的所有类。

以我的方式思考PHPUnit在这里做了错误的事情,通过选择它不应该用于特定测试的依赖项。

0 个答案:

没有答案
相关问题