是否可以在不扩展 PHPUnit_Framework_TestCase 的情况下使用 PHPUnit 断言?

Is it possible to use PHPUnit assertions without extending PHPUnit_Framework_TestCase?

也许这个问题看起来很奇怪,但这是我正在尝试解决的问题...首先,请记住我更像是一个 Java 开发人员,我正在习惯与 PHP 一起工作,所以也许我的思维过程有问题!

我正在测试我使用 Symfony 构建的网站。对于我的组件测试,我创建了我的测试 class 扩展 WebTestCase 并且我的测试有一组如下所示的断言来验证页面标题是否在我想要的位置并包含我期望的内容:

$text = "Page Title";
$selector = "h2#pageHeading";
$this->assertEquals(1, $crawler->filter($selector)->count(), "Found wrong number of elements using selector ".$selector);
$this->assertEquals(trim($text),
        trim($crawler->filter($selector)->text()),
        "Element $selector didn't have expected text");

然后我为站点内的其他页面编写了更多测试,在所有这些页面中我都想测试标题是否存在,所以为了能够重用代码我将上面的代码重构为一个函数parent class 其他测试 classes 重用:

function assertPageTitle($text) {
    $selector = "h2#pageHeading";
    $this->assertEquals(1, $crawler->filter($selector)->count(), "Found wrong number of elements using selector ".$selector);
    $this->assertEquals(trim($text),
            trim($crawler->filter($selector)->text()),
            "Element $selector didn't have expected text");
}

我在测试中调用了该方法。随着测试的发展,我可以重构更多类似的 "complex assertions",并且所有这些都转到 parent class,从而使我的 parent class 膨胀成一个大型断言容器:

protected function assertSelectedOptionContainsTextValue($selector, $text, $value, $crawler) {
    ...
}

protected function assertMenusContainItems($menus, $crawler) {
    ...
}

protected function assertErrorMessageShown($message, $crawler) {
    ...
}

... (more and more) ...

你懂的。此时我的下一个想法是将所有这些 "complex assertions" 重构为其他 classes,可能遵循 Page Object 模式,但其他 classes 将无法访问到 assertEquals 方法,除非其他 classes 也扩展 WebTestCase 或至少 PHPUnit_Framework_TestCase,这似乎不是一个好主意...

那么有没有一种无需扩展基础 PHPUnit classes 即可访问 assertEquals 方法(及相关方法)的简便方法?我能以某种方式使用组合吗?

首先,您在 "generic" 函数的开头覆盖了 $text 变量 - 但我知道您只想展示想法。

其次,对这种测试使用单元测试并不是最好的选择。我认为您应该提取标题逻辑以分隔 类,然后通过 PHPUnit 或使用更合适的测试解决方案(如 Behat 或 Selenium)对其进行测试。

如果您仍然没有改变意见...您必须至少扩展 PHPUnit_Framework_TestCase 每当您想使用 PHPUnit 进行测试时。

小提示:Traits 可以很好地提取您的断言。

PHPUnit 的内置断言在 PHPUnit_Framework_Assert class 中作为 public 静态方法实现。例如,只需将它们调用为 PHPUnit_Framework_Assert::assertTrue()

为了在特征中创建可重用的 phpunit 断言。这可以用于许多测试用例。您可以使用静态调用 PHPUnit_Framework_Assert::assertSame 的特征,快速示例如何实现它:

<?php

namespace Tests\Foo;

use PHPUnit_Framework_Assert;

trait AssertTrait
{
    public function assertInTraitAlwaysFailing()
    {
        PHPUnit_Framework_Assert::assertSame(1, 2, 'always failing');
    }
}

它将充当助手,可以在许多需要相同断言以防止重复的地方使用。