我已经完成了尽职调查,但我认为到目前为止,任何问题都没有涉及到这个问题。
我的情况是我的PHP代码根据配置属性生成类定义。
类定义基本上是数据持有者,可以有:
在某些配置情况下,生成的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在这里做了错误的事情,通过选择它不应该用于特定测试的依赖项。