为什么 "assertSelectorExists()" 断言不显示我指定的失败消息?

Why doesn't the "assertSelectorExists()" assertion show the failure message that I specify?

我试图在 PHPUnit 9.5.11 测试失败时显示自定义消息(正在测试的 URL)。在我的 Symfony 4.4 应用程序中。

class很简单:

class BaseTestCase extends PantherTestCase

在我的测试中,我:

$client = static::createPantherClient();
$crawler = $client->request('GET', $url);
$this->assertSelectorExists('.some-class', $url); // <- this should display the tested $url, since the second argument is supposed to be the message to show on failure

但是当测试失败时,我得到的只是:

  1. App\Tests\PropertyListingTest::testListingWithFullQueryString with data set #0 ('') Facebook\WebDriver\Exception\NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".some-class"} (Session info: headless chrome=97.0.4692.71)

这是怎么回事?如果我 运行 这个:

$this->assertEquals("a", "b", "!!!!TEST FAILED!!!!");

它按预期工作:

!!!!TEST FAILED!!!! Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'a' +'b'

如果我理解你的意思

$client = static::createPantherClient();
$response = $client->request('GET', $url);
$crawler = $response->getContent();

现在 crawler 变量包含您从 url 变量

获得的实际数据

如何继续测试此信息取决于您

在我看来,这种行为实际上像是一个错误。

因为如果你看看 assertSelectorExists 内部做了什么(见下文)...

public static function assertSelectorExists(string $selector, string $message = ''): void
{
    $client = self::getClient();

    if ($client instanceof PantherClient) {
        $element = self::findElement($selector); // NoSuchElementException is thrown here
        self::assertNotNull($element, $message); // so the message is never used
        
        return;
    }

    self::assertNotEmpty($client->getCrawler()->filter($selector));
}

...您会注意到它期望 findElement 到 return null 以防万一找不到元素。但问题是 findElement 在这种情况下不会 return null,它会抛出异常。

为了解决这个问题,我会像这样制作我自己的 assertSelectorExists 版本:

$client = static::createPantherClient();
$crawler = $client->request('GET', $url);
$this->assertSelectorExistsSafe($client, '.some-class', $url);

protected function assertSelectorExistsSafe($client, $selector, $message)
{
    try {
        $element = $client->findElement($client->createWebDriverByFromLocator($selector));
    } catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) {
        $element = null;
    }
    self::assertNotNull($element, $message);
}