PHPUnit-Immediate-Printer icon indicating copy to clipboard operation
PHPUnit-Immediate-Printer copied to clipboard

Call to undefined method PHPUnit_Extensions_Selenium2TestCase_WebDriverException::getPreviousWrapped()

Open borekb opened this issue 7 years ago • 4 comments

I get this error when trying to run Selenium test case with your reporter:

Error: Call to undefined method PHPUnit_Extensions_Selenium2TestCase_WebDriverException::getPreviousWrapped() in /opt/versionpress/vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php:159
Stack trace:
#0 /opt/versionpress/vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php(103): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->writeException(Object(PHPUnit_Extensions_Selenium2TestCase_WebDriverException))
#1 /opt/versionpress/vendor/scriptfusion/phpunit-immediate-exception-printer/src/PhpUnit5Printer.php(26): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->onEndTest(Object(PHPUnit_Framework_TestSuite), 0)
#2 /opt/versionpress/vendor/phpunit/phpunit/src/Framework/TestResult.php(399): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->endTest(Object(PHPUnit_Framework_TestSuite), 0)
#3 /opt/versionpress/vendor/phpunit/phpunit/src/Framework/TestSuite.php(700): PHPUnit_Framework_TestResult->endTest(Object(PHPUnit_Framework_TestSuite), 0)
#4 /opt/versionpress/vendor/phpunit/phpunit/src/Framework/TestSuite.php(722): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
#5 /opt/versionpress/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(517): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
#6 /opt/versionpress/vendor/phpunit/phpunit/src/TextUI/Command.php(186): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array, true)
#7 /opt/versionpress/vendor/phpunit/phpunit/src/TextUI/Command.php(116): PHPUnit_TextUI_Command->run(Array, true)
#8 /opt/versionpress/vendor/phpunit/phpunit/phpunit(52): PHPUnit_TextUI_Command::main()
#9 {main}

Can I provide any more info? Thanks.

borekb avatar May 21 '18 20:05 borekb

I don't know anything about Selenium. I guess it's not compatible.

Bilge avatar May 21 '18 20:05 Bilge

The problem is probably that PHPUnit_Extensions_Selenium2TestCase_Exception doesn't inherit from ExceptionWrapper:

https://github.com/giorgiosironi/phpunit-selenium/blob/8e4cf0271d82a44324e3dfebf0ea84c467b39317/PHPUnit/Extensions/Selenium2TestCase/Exception.php#L56

Then this code fails:

https://github.com/ScriptFUSION/PHPUnit-Immediate-Exception-Printer/blob/de2f8a0987ff1c0d835e3ee36db0e86920f68ee1/src/Printer.php#L159

I think the code here could try to call getPreviousWrapped() but if the exception class doesn't implement it, just carry on.

borekb avatar May 22 '18 06:05 borekb

Had this same error too today, running as part of CakePHP2 PHPUnit.

$ php -v
PHP 7.2.10-0ubuntu0.18.04.1 (cli) (built: Sep 13 2018 13:45:02) ( NTS )

$ grep -v / lib/Cake/VERSION.txt
2.10.12

$ app/Vendor/bin/phpunit --version
PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

Error from test:

$ app/Console/cake test app All
…
lots of lines later
…
 92% E SaveApiPostTest::testSaveNewWithoutAnyProfiles (134 ms)

Error: Call to undefined method PHPUnit_Framework_Error_Notice::getPreviousWrapped()
#0 /vagrant/project/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php(103): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->writeException(Object(PHPUnit_Framework_Error_Notice))
#1 /vagrant/project/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/PhpUnit5Printer.php(26): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->onEndTest(Object(SaveApiPostTest), 0.1339910030365)
#2 /vagrant/project/app/Vendor/phpunit/phpunit/src/Framework/TestResult.php(399): ScriptFUSION\PHPUnitImmediateExceptionPrinter\PhpUnit5Printer->endTest(Object(SaveApiPostTest), 0.1339910030365)
#3 /vagrant/project/app/Vendor/phpunit/phpunit/src/Framework/TestResult.php(889): PHPUnit_Framework_TestResult->endTest(Object(SaveApiPostTest), 0.1339910030365)
#4 /vagrant/project/app/Vendor/phpunit/phpunit/src/Framework/TestCase.php(868): PHPUnit_Framework_TestResult->run(Object(SaveApiPostTest))
#5 /vagrant/project/lib/Cake/TestSuite/CakeTestCase.php(84): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
#6 /vagrant/project/app/Vendor/phpunit/phpunit/src/Framework/TestSuite.php(733): CakeTestCase->run(Object(PHPUnit_Framework_TestResult))
#7 /vagrant/project/app/Vendor/phpunit/phpunit/src/Framework/TestSuite.php(733): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
#8 /vagrant/project/app/Vendor/phpunit/phpunit/src/TextUI/TestRunner.php(517): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
#9 /vagrant/project/lib/Cake/TestSuite/CakeTestRunner.php(75): PHPUnit_TextUI_TestRunner->doRun(Object(CakeTestSuite), Array)
#10 /vagrant/project/lib/Cake/TestSuite/CakeTestSuiteCommand.php(98): CakeTestRunner->doRun(Object(CakeTestSuite), Array)
#11 /vagrant/project/lib/Cake/Console/Command/TestShell.php(283): CakeTestSuiteCommand->run(Array)
#12 /vagrant/project/lib/Cake/Console/Command/TestShell.php(268): TestShell->_run(Array, Array)
#13 /vagrant/project/lib/Cake/Console/Shell.php(462): TestShell->main()
#14 /vagrant/project/lib/Cake/Console/ShellDispatcher.php(219): Shell->runCommand('app', Array)
#15 /vagrant/project/lib/Cake/Console/ShellDispatcher.php(66): ShellDispatcher->dispatch()
#16 /vagrant/project/app/Console/cake.php(36): ShellDispatcher::run(Array)
#17 {main}

Note: CakePHP2 is a bit of an odd thing: usually you directly invoke bin/phpunit but with CakePHP2 you need to run it through the framework, which has its own bootstrapping stuff.

The error happens when an object of PHPUnit_Framework_Error_Notice is passed to \ScriptFUSION\PHPUnitImmediateExceptionPrinter\Printer::writeException. The definition of this class in the version of PHPUnit I'm using:

class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error
{
    public static $enabled = true;
}

and further

class PHPUnit_Framework_Error extends PHPUnit_Framework_Exception { … }

But getPreviousWrapped() is defined on \PHPUnit_Framework_ExceptionWrapper which extends PHPUnit_Framework_Exception.

In short, in phpunit/src/Framework/Error there are three classes defined, none of which extends or is wrapped in ExceptionWrapper but which may be received.

@borekb

I think the code here could try to call getPreviousWrapped() but if the exception class doesn't implement it, just carry on.

I tried this with something like:

        do {
            $exceptionStack[] = $exception;
        } while (method_exists($exception, 'getPreviousWrapped') && $exception = $exception->getPreviousWrapped());

but then the follow-up code behaves odd.

Besides, there is an error happening and it should be shown.

After some testing I found something "working": if the exception passed is not wrapped => wrap it!

diff --git a/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php b/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php
index db2a81702..f8a96b349 100644
--- a/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php
+++ b/app/Vendor/scriptfusion/phpunit-immediate-exception-printer/src/Printer.php
@@ -4,6 +4,7 @@ namespace ScriptFUSION\PHPUnitImmediateExceptionPrinter;
 use PHPUnit\Framework\AssertionFailedError;
 use PHPUnit\Framework\ExceptionWrapper;
 use PHPUnit\Framework\Test;
+use PHPUnit_Framework_ExceptionWrapper;

 trait Printer
 {
@@ -155,6 +156,10 @@ trait Printer
         $this->writeNewLine();

         do {
+            if (!$exception instanceof PHPUnit_Framework_ExceptionWrapper) {
+                $exception = new PHPUnit_Framework_ExceptionWrapper($exception);
+            }
+
             $exceptionStack[] = $exception;
         } while ($exception = $exception->getPreviousWrapped());

With this I was able to see the correct error (and trace):

PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

 33% E SaveApiPostTest::testSaveNewWithoutAnyProfiles (216 ms)


 PHPUnit_Framework_Error_Notice  Undefined index: message


/vagrant/project/sub-project/app/Services/Robot/Executor.php:155
/vagrant/project/sub-project/app/Services/Robot/Executor.php:79
/vagrant/project/app/Model/Post.php:939
/vagrant/project/app/Test/Case/SubProject/SaveApiPostTest.php:112
/vagrant/project/lib/Cake/TestSuite/CakeTestCase.php:84
/vagrant/project/lib/Cake/TestSuite/CakeTestRunner.php:75
/vagrant/project/lib/Cake/TestSuite/CakeTestSuiteCommand.php:98
/vagrant/project/lib/Cake/Console/Command/TestShell.php:283
/vagrant/project/lib/Cake/Console/Command/TestShell.php:268
/vagrant/project/lib/Cake/Console/Shell.php:462
/vagrant/project/lib/Cake/Console/ShellDispatcher.php:219
/vagrant/project/lib/Cake/Console/ShellDispatcher.php:6

mfn avatar Oct 23 '18 06:10 mfn

My fork at https://github.com/mfn/phpunit-immediate-exception-printer contains similar code so this might even work

mfn avatar Dec 18 '19 22:12 mfn

This should no longer happen in v3. Let me know if you find otherwise.

Bilge avatar Jul 21 '24 10:07 Bilge