Eric Cope
Eric Cope

Reputation: 877

PHPUnit, Selenium Basic Test Fails with Fatal Error

I am running PHP 5.3.6 and the latest version of PHPUnit from Github. When I copy example 17.1 from the docs, it suffers a fatal error when the assertTitle fails. I get this error message:

Fatal error: Call to a member function toString() on a non-object in <path>/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumTestCase.php on line 1041

When I change the assertion to pass, PHPUnit runs just fine.

I dug up the line and this is the snippet :

protected function onNotSuccessfulTest(Exception $e)
    {
        if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
            $buffer  = 'Current URL: ' . $this->drivers[0]->getLocation() .
                       "\n";
            $message = $e->getComparisonFailure()->toString();

$e->getComparisonFailure() returns NULL, not an object. What am I doing incorrectly?

UPDATE:

I found the reason for the failure, although a fix isn't on my horizon yet.

On line 92 of PHPUnit/Framework/Constraint.php, it calls using

$this->fail($other,$description)

which is defined as:

protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)

Since no PHPUnit_Framework_ComparisonFailure is passed, NULL is passed on line 141 of PHPUnit/Framework/Constraint.php

 

throw new PHPUnit_Framework_ExpectationFailedException(           $failureDescription,           $comparisonFailure         );

which is fetched by getComparisonFailure() which is supposed to return an object, as described above.

Any more ideas?

Upvotes: 3

Views: 1989

Answers (3)

HNygard
HNygard

Reputation: 4796

This problem relates to issue #66 on the PHPUnit-Selenium project on Github. I've made one commit that fixes this problem and one that fixes the "setCustomMessage()" problem which Matthew mentioned. I think both problems where introduced by one commit in PHPUnit 3.6

$message = $e->getComparisonFailure()->toString();

Where changed to

// ?: Is "comparison failure" set and therefore an object? (fixes issue #66)
if(is_object($e->getComparisonFailure())) {
    // -> Comparison failure is and object and should therefore have the toString method
    $message = $e->getComparisonFailure()->toString();
}
else {
    // -> Comparison failure is not an object. Lets use exception message instead
    $message = $e->getMessage();
}

And at the end of onNotSuccessfulTest():

$e->setCustomMessage($buffer);

Where changed to:

// ?: Does the setCustomMessage method exist on the exception object? (fixes issue #67)
if(method_exists($e, 'setCustomMessage')) {
    // -> Method setCustomMessage does exist on the object, this means we are using PHPUnit 
    //    between 3.4 and 3.6
    $e->setCustomMessage($buffer);
}
else {
    // -> Method setCustomerMessages does not exist on the object, must make a new exception to 
    //    add the new message (inc. current URL, screenshot path, etc)
    $e = new PHPUnit_Framework_ExpectationFailedException($buffer, $e->getComparisonFailure());
}

Hopefully both changes will be accepted into the PHPUnit-Selenium project. At least it fixed the problems I where having with the latest updates for PHPUnit and PHPUnit-Selenium from PEAR.

Upvotes: 3

Matthew
Matthew

Reputation: 11

I replaced $message = $e->getComparisonFailure()->toString(); to be:

if($e->getComparisonFailure() == NULL)
{
    $message = $e;
}
else
{
    $message = $e->getComparisonFailure()->toString();
}

I also reverted PHPUnit_Framework_ExpectationFailedException back to 3.5.3 so it has setCustomMessage()

Upvotes: 1

Klaidi
Klaidi

Reputation: 56

Just replace $message = $e->getComparisonFailure()->toString(); with $message = $e->getComparisonFailure()->exceptionToString;

It works fine for me

Upvotes: 4

Related Questions