PHPUnit 配置(phpunit.xml)——在引导程序中加载?

发布于 2024-09-28 00:01:44 字数 2072 浏览 6 评论 0原文

情况

我们在项目中使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

骄兵必败 2024-10-05 00:01:45

我的解决方案是添加一个 bash 函数

function phpu ()
{
  phpunit --colors --bootstrap ~/path/to/bootstrap.php "$@";
}

,然后将其添加到所有 dev .bashrc 文件中,他们可以切换到使用它。

我们喜欢从 vim 调用它们,所以我必须将其添加到 .vimrc 中: set shellcmdflag=-ic

然后添加 nmap ;t:! phpu % 运行您当前所在的测试文件。

My solution is to add a bash function

function phpu ()
{
  phpunit --colors --bootstrap ~/path/to/bootstrap.php "$@";
}

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.

我的奇迹 2024-10-05 00:01:45

您可以更新启动脚本(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.

棒棒糖 2024-10-05 00:01:44

直接回答:不,你不能这样做。

更长的故事 - 通过改变开发人员的习惯可以更好地解决此类问题。

我们是这样做的:

  • 所有开发人员总是从测试根目录运行测试,该根目录具有唯一的 phpunit.xml 以及所有必要的配置 - 包括引导程序,它设置一个类自动加载器。
  • 我们没有这样的测试套件,测试使用目录进行分组,任何地方都没有 AllTests.php,因为它没有必要。 PHPUnit 可以获取目录名称并在其中运行所有测试。
  • 仍然可以通过提供单个测试或整个测试套件的路径(通过提供目录的路径)来运行任何单个测试。它必须始终从测试根目录完成,否则将无法工作。

这样做意味着放弃从任何目录启动 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:

  • All developers always run the tests from the tests root directory, which has the sole phpunit.xml with all the necessary configuration - including bootstrap, which sets up an class autoloader.
  • We don't have testsuites as such, tests are grouped using directories, no AllTests.php anywhere, because its not necessary. PHPUnit can take a name of directory and run all tests inside it.
  • Its still possible to run any single test by giving a path to it or whole testsuite (by giving path to the directory). It just has to be done from the tests root directory all the time or it won't work.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文