PHPUnit 配置(phpunit.xml)——在引导程序中加载?
情况
我们在项目中使用 PHPUnit,并使用 phpunit.xml
来确保诸如 backupGlobals
之类的功能关闭。
为了进一步确保包含路径已设置且自动加载处于活动状态,我们还级联了测试引导程序。也就是说,每个测试和所有测试套件在顶部都有一个 require_once(__DIR__ . '/../bootstrap.php');
,一直到基本文件夹级别,其中它显然读取 require_once(__DIR__ . '/bootstrap.php');
,并且实际的引导文件驻留。
本质上,我们的测试是自主的。您可以调用任何文件夹中的任何 AllTests.php
以及任何 *Test.php
本身,它们将以正确的配置运行。
除了没有。 '稍等一下。'
只有当我们强制开发人员使用 phpunit --configuration=path/to/phpunit.xml
或它们位于文件夹中时,情况才会如此与 phpunit.xml
(以便 PHPUnit 在执行时将其从当前工作目录中拉出)。
有时,这使得确定为什么一个开发人员机器上的测试失败以及为什么它们在另一台机器上运行变得非常困难。只是需要忘记引导程序并不是我们需要拥有相同测试环境的唯一东西。请记住,如果您尝试过,您就不会忘记引导程序,因为它位于测试本身中,因此忘记了其他设置,尤其是像这样的通常可选的设置(如果您位于包含 phpunit.xml 的文件夹中) ,它是自动拉动的),很简单。
事实上——这样的事情已经发生过好几次了。
问题
有没有一种方法可以提供在正在运行的测试文件中使用的phpunit.xml
,例如在我们方便无处不在的引导文件中,而不是提供事先将其加载到 PHPUnit,是通过命令行开关还是通过其目录?
粗略地浏览一下代码表明答案是否定的 - 配置良好且确实似乎已加载在提取测试文件之前:
[PHPUnit/TextUI/Command.php]
...
if (isset($this->arguments['configuration'])) {
$configuration = PHPUnit_Util_Configuration::getInstance(
$this->arguments['configuration']
);
$phpunit = $configuration->getPHPUnitConfiguration();
...
考虑到配置可以包含测试白名单或黑名单,这确实有一定意义。
实际上,在测试引导程序本身中加载测试过滤器是没有意义的,因此这是窗口外潜在配置的一半,但 PHPUnit 的实际行为标志......
[sample of part of our phpunit.xml]
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
syntaxCheck="false"
processIsolation="false"
colors="true">
也许除了“颜色”之外,我认为测试本身应该能够在某种程度上决定。
安慰奖...
诚然,现在我很高兴知道我是否可以从引导文件中教授 PHPUnit backupGlobals="false"
(如果有人知道一种方法的话)。
(如果没有结果,我追求的实际答案可能是将 phpunit.xml
复制到所有子文件夹中。我想避免该解决方案,因为它会创建冗余副本,并且如果我们曾经选择更改设置...是的,哎哟!)
Situation
We're using PHPUnit in our project and are using a phpunit.xml
to ensure things like backupGlobals
is turned off.
To further ensure the include path is set and autoloading is active, we also cascade our test bootstraps. That is to say, every test and alltests-suite has a require_once(__DIR__ . '/../bootstrap.php');
at the top, all the way up to the base folder level, where it obviously reads require_once(__DIR__ . '/bootstrap.php');
, and the actual bootstrap file resides.
Essentially, our tests are autonomous. You can call any AllTests.php
in any folder and any *Test.php
by itself and they'll run with the right configuration.
Except no. 'Wait a moment.'
That's only true if we either force our developers to use phpunit --configuration=path/to/phpunit.xml
or they're in the folder with the phpunit.xml
(so that PHPUnit pulls it out of the current working directory when it is executed).
Occasionally, this makes it incredibly hard to determine why tests on one developer's machine are breaking and why they're running on another. It just takes forgetting that the bootstrap is not the only thing we need to have the same test environment. Keep in mind that since you couldn't forget the bootstrap if you tried, because it's in the tests themselves, forgetting other settings, especially usually-optional ones like that (if you're in the folder with the phpunit.xml
, it's automatically pulled), is easy.
In fact - it's happened a few times.
Question
Is there a way I can supply which phpunit.xml
to use in the test file being run, such as in our conveniently ubiquitous bootstrap file, rather than supplying it to PHPUnit beforehand, be that by command-line switch or by being in its directory ?
A cursory glance at the code suggests the answer is no - configuration well and truly seems to be loaded before test files are even pulled:
[PHPUnit/TextUI/Command.php]
...
if (isset($this->arguments['configuration'])) {
$configuration = PHPUnit_Util_Configuration::getInstance(
$this->arguments['configuration']
);
$phpunit = $configuration->getPHPUnitConfiguration();
...
That does make some sense, given that the configuration can contain test white- or blacklists.
Really, it wouldn't make sense to load test filters in the test bootstrap itself, so that's half the potential configuration out the window with, but the actual behavioural flags of PHPUnit...
[sample of part of our phpunit.xml]
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
syntaxCheck="false"
processIsolation="false"
colors="true">
...perhaps with the exception of 'colors' strikes me as something that the test itself should be able to decide on some level.
Consolation prize for...
Admittedly, right now I'd be happy just knowing if I can teach PHPUnit backupGlobals="false"
from the bootstrap file, if someone knows of a way.
(If fruitless, the practical answer I'll pursue will probably be to copy the phpunit.xml
into all subfolders. I'd like to avoid that solution since it creates redundant copies, and if we ever choose to change a setting... yeah, ouch!)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我的解决方案是添加一个 bash 函数
,然后将其添加到所有 dev .bashrc 文件中,他们可以切换到使用它。
我们喜欢从 vim 调用它们,所以我必须将其添加到 .vimrc 中:
set shellcmdflag=-ic
然后添加 nmap ;t:! phpu % 运行您当前所在的测试文件。
My solution is to add a bash function
Then add this to all dev .bashrc files and they can switch to using that.
We like to call them from
vim
so I had to add this to.vimrc
:set shellcmdflag=-ic
Then you add
nmap ;t :! phpu %
to run the test file you're currently in.您可以更新启动脚本(Windows bat 文件或 *nix 上的 shell)并在其中配置逻辑来配置 phpunit.xml 的位置。如果在当前目录中,则使用它,否则指向主目录。
不过,我也同意 Anti 的观点,即所有测试都应该始终运行,因为您希望确保更改(即使是在目录分支中)不会影响其他代码。因此,总是从树顶跑。这也要求测试快速执行,但我在这方面对 PHPUnit 并没有真正的问题。
在每个目录中维护 PHPUnit.xml 将是一场维护噩梦,除非从其他路径进行符号链接以确保只有一个实际文件。
You could update the start script (Windows bat file, or shell on *nix) and have logic in there to configure to the location of the phpunit.xml. If it is in the current directory, use it, otherwise point to the main one.
I also agree with Anti though, that all the tests should always be run, as you want to ensure that the changes, even in a directory branch, do not affect other code. Therefore, always run from the top of the tree. This also requires that the test execute quickly, but I have not really had a problem with PHPUnit on that.
Maintaining the PHPUnit.xml in each directory would be a maintenance nightmare, unless is was symbolically linked from other paths to ensure there was only one actual file.
直接回答:不,你不能这样做。
更长的故事 - 通过改变开发人员的习惯可以更好地解决此类问题。
我们是这样做的:
phpunit.xml
以及所有必要的配置 - 包括引导程序,它设置一个类自动加载器。这样做意味着放弃从任何目录启动 PHPUnit 的自由,但说实话 - 我不觉得这有什么损失。
收益要大得多:内务代码的数量减少了,开发人员不会忘记任何事情,因此结果是一致的。
Direct answer: No, you can't do that.
Longer story - this kind of problem is better solved by changing the habits of developers.
Here is we do it:
phpunit.xml
with all the necessary configuration - including bootstrap, which sets up an class autoloader.Doing it like this means giving up the freedom of starting PHPUnit from any directory, but to be honest - I don't feel like that's a loss at all.
The gains are much bigger: the amount of housekeeping code is reduced, developers cannot forget anything and results are therefore consistent.