【问题标题】:Is it possible to use PHPUnit assertions without extending PHPUnit_Framework_TestCase?是否可以在不扩展 PHPUnit_Framework_TestCase 的情况下使用 PHPUnit 断言?
【发布时间】:2015-03-22 20:05:02
【问题描述】:

也许这个问题看起来很奇怪,但这是我要解决的问题...首先,请记住,我更像是一个习惯于使用 PHP 的 Java 开发人员,所以也许问题是我的思维过程!

我正在测试一个使用 Symfony 构建的网站。对于我的组件测试,我创建了扩展 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");

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

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");
}

我在测试中调用了该方法。随着测试的发展,我可以重构更多类似的“复杂断言”,所有这些都转到父类,从而将我的父类膨胀成一个庞大的断言容器:

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

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

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

... (more and more) ...

你明白了。在这一点上,我的下一个想法是将所有这些“复杂断言”重构到其他类中,可能遵循Page Object 模式,但是其他类将无法访问assertEquals 方法,除非那些其他类也扩展@ 987654328@或至少PHPUnit_Framework_TestCase,这似乎不是一个好主意...

那么有没有一种简单的方法来访问assertEquals 方法(和相关的)而无需扩展基本的PHPUnit 类?我可以以某种方式使用组合吗?

【问题讨论】:

  • 如果你想测试你的 UI 代码,你真的应该使用 selenium。 phpunit.de/manual/current/en/selenium.html
  • 我不太确定我是否同意这一点。 Selenium 缓慢且易碎,很容易因神秘原因而失败。我们在 PHP 测试无法达到的地方使用 Selenium,但仅此而已。

标签: php unit-testing symfony phpunit


【解决方案1】:

首先,您在“通用”函数的开头覆盖 $text 变量 - 但我知道您只想展示想法。

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

如果你还没有改变你的观点...你必须至少扩展PHPUnit_Framework_TestCase 每当你想使用 PHPUnit 进行测试。

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

【讨论】:

  • 感谢您指出代码中的错字,现已更正。我试图避免扩展 PHPUnit_Framework_TestCase 可能是因为我正在考虑使用 Java(您可以在其中导入断言并使用它们)。 Traits 的选择听起来很有趣,但它似乎从 5.4.0 开始可用,我坚持使用 5.3.24 :(
  • 所以我认为你应该改变你的心态 :) 没有比这更好的方法了。
【解决方案2】:

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

【讨论】:

  • 好点。实际上,即使我要去应用@user2970075 的建议,这肯定更接近我原来问题的答案。我会这样标记它。谢谢!
【解决方案3】:

为了在 trait 中创建可重用的 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');
    }
}

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

【讨论】:

    猜你喜欢
    • 2018-06-05
    • 2012-08-11
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    相关资源
    最近更新 更多