Functional test with PHPUnit gives me Unexpected character in input - php

I am developing a web app with Symfony2. My application connects to some external services, which I mocked using Ruby. This is a snippet of my ruby mock
#Bunch of stuff...
after do
response['Content-type'] = 'application/json'
end
#Bunch of stuff...
get '/configure/set_result' do
#Bunch of stuff...
JSON.generate 'success' => true,
"message" => "whatever"
end
In one of the functional tests I am doing I call this method
<?php
class MyControllerTest extends WebTestCase {
protected function setUp() {
$this->client = static::createClient();
}
public function testWhatever() {
$this->callMyMock(22);
//Unimportant stuff
}
private function callMyMock($result) {
$crawler = $this->client->request('GET', "http://localhost:5995/configure/set_result?resultCode=$result");
}
}
The problem is that in the log I get a lot of PHP warning (that actually slow down PHPUnit quite a lot. This is an example of the output:
WebApp.PHPUnitTests:
[exec] PHPUnit 3.7.19 by Sebastian Bergmann.
[exec]
[exec] Configuration read from C:\Work\New Products Trunk\Software\WebApp\symfony2\app\phpunit.xml.dist
[exec]
[exec] PHP Warning: Unexpected character in input: '→' (ASCII=26) state=0 in C:\Work\New Products Trunk\Soft
endor\symfony\symfony\src\Symfony\Bridge\Twig\Extension\CodeExtension.php on line 140
[exec] PHP Stack trace:
[exec] PHP 1. {main}() C:\_Wallet\phpunit.phar:0
[exec] PHP 2. PHPUnit_TextUI_Command::main() C:\_Wallet\phpunit.phar:527
[exec] PHP 3. PHPUnit_TextUI_Command->run() phar://C:/_Wallet/phpunit.phar/PHPUnit/TextUI/Command.php:129
...
...
...
...
What am I doing wrong?

This is a known bug when running from .phar files, because in this case the function that does "highlighting" does not get a filename, but the content of the phar, hence the unexpected input.
Some background: your test may be triggering an exception which gets handled by internal symfony ErrorHandler which displays nicely formatted stack traces, this formatting is what triggers this warning.
It has been fixed in this PR: https://github.com/symfony/symfony/pull/8721/files
And details are in this Issue: https://github.com/symfony/symfony/issues/7798

Related

PHPunit test errors with `Parse error` on CI

I'm unit testing my code with the help of phpunit 9.3.8. The tests run fine on my local dev environment (I'm running Windows 10, PHP 7.4.2 with Xdebug 2.9.2) but fail because of a parse error when I try to run phpunit on Gitlab CI (The CI runs the latest alpine linux image).
The error is:
$ composer run test
> phpunit
PHPUnit 9.3.8 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.23 with Xdebug 2.9.8
Configuration: /builds/gaspacchio/back-to-the-future/phpunit.xml
Reporter
✘ Can set short message [6.05 ms]
│
│ ParseError: syntax error, unexpected 'int' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)
│
│ /builds/gaspacchio/back-to-the-future/src/api/utilities/Reporter.php:21
│ /builds/gaspacchio/back-to-the-future/src/api/tests/ReporterTest.php:12
│
// More errors
Time: 00:01.970, Memory: 310.00 MB
ERRORS!
Tests: 6, Assertions: 0, Errors: 6.
Generating code coverage report in Clover XML format ... done [00:00.330]
PHP Warning: fopen(/builds/gaspacchio/back-to-the-future/): failed to open stream: Is a directory in /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/src/Util/Printer.php on line 89
PHP Stack trace:
PHP 1. {main}() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/phpunit:0
PHP 2. PHPUnit\TextUI\Command::main() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/phpunit:61
PHP 3. PHPUnit\TextUI\Command->run() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/src/TextUI/Command.php:100
PHP 4. PHPUnit\TextUI\TestRunner->run() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/src/TextUI/Command.php:147
PHP 5. PHPUnit\Util\Printer->__construct() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:756
PHP 6. fopen() /builds/gaspacchio/back-to-the-future/vendor/phpunit/phpunit/src/Util/Printer.php:89
Code Coverage Report:
2020-10-13 10:12:09
Summary:
Classes: 0.00% (0/11)
Methods: 0.00% (0/38)
Paths: 0.00% (0/7)
Branches: 0.00% (0/7)
Lines: 0.00% (0/397)
Script phpunit handling the test event returned with error code 2
Line 21 of the Reporter.php file is below:
<?php namespace utilities\Reporter;
/**
* The Reporter class is responsible for returning data to the client.
*/
class Reporter
{
/** This is the code of the answer.
* (more comments)
* #var int The status code.
*/
private int $code; //<-- This is line number 21
And the line 12 of ReporterTest.php is:
<?php
use PHPUnit\Framework\TestCase;
use utilities\Reporter\Reporter;
class ReporterTest extends TestCase
{
protected $reporter;
protected function setUp(): void
{
$this->reporter = new Reporter(); // <-- Line 12 is here
}
}
I'm using the fixtures function of PHPunit, defined as :
PHPUnit supports sharing the setup code. Before a test method is run, a template method called setUp() is invoked. setUp() is where you create the objects against which you will test.
Type hinting of object properties is in PHP 7.4 and this is running
PHPUnit 9.3.8 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.23 with Xdebug 2.9.8
It's basically a PHP version conflict,
for some reason PHPUnit is trying to parse it like older PHP versions where private int $code; is invalid (and private $code; should be used instead).
Oh, just noticed your Windows system is running PHP 7.4
but Gitlab CI image has PHP 7.3.23 installed!

How to configure PHPUnit to regard dataprovider error as failure and not warning?

I run my PHP unit tests using PHPUnit. When a dataprovider fails to load, it results in a warning, instead of a failure.
Up until PHPUnit version 4, when a dataprovider fails to load, a failure is shown in the PHPUnit output.
Starting with PHPUnit 5, a warning is being issued instead. This is a problem for when running the tests using a script (for example in continuous integration) so I don't see the results.
Another difference is when running the code with PHP 5 vs PHP 7. When running the tests with PHP 5, instead of seeing the PHPUnit output I immediately get a PHP Fatal Error. With PHP 7 it only shows the failure/warning when PHPUnit gets to the failed test. This leads me to believe that this has something to do with the error_handler set by PHPUnit, that can catch the error that PHP7 throws but PHP5 doesn't.
Here is my PHP code:
class TestTest extends PHPUnit_Extensions_Database_TestCase
{
/**
* #dataProvider provider_sample
*/
public function test_sample($foo)
{
$this->assertString($foo);
}
public function provider_sample()
{
return [
[ClassName::string] // no such class, this should fail
];
}
public function getDataset()
{
return new ArrayDataSet([]);
}
}
Here are the results of running PHPUnit 4:
PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
Runtime: PHP 7.2.5
Configuration: /home/some-path/phpunit.xml
Warning: The Xdebug extension is not loaded
No code coverage will be generated.
F
Time: 120 ms, Memory: 14.00MB
There was 1 failure:
1) Warning
The data provider specified for TestTest::test_sample is invalid.
Class 'ClassName' not found
FAILURES!
Tests: 1, Assertions: 0, Failures: 1.
And here is the results of running the same code with PHPUnit 5:
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.
Runtime: PHP 7.2.5
Configuration: /home/some-path/phpunit.xml
Error: No code coverage driver is available
W 1 / 1 (100%)
Time: 99 ms, Memory: 14.00MB
There was 1 warning:
1) Warning
The data provider specified for TestTest::test_sample is invalid.
Class 'ClassName' not found
WARNINGS!
Tests: 1, Assertions: 0, Warnings: 1.
The results of PHPUnit 4 is what I expect and want.
Is there a way to configure PHPUnit 5 and higher to behave the same?
I don't think you can do exactly what you're asking for, but if you want to integrate PHPUnit with a continuous integration server (for example, Jenkins), then you can spawn a JUnit-compatible report with warnings reported as errors instead and tell Jenkins to use that instead of PHPUnit report.
To do that, you will need to extend JUnit logger shipped with PHPUnit:
use PHPUnit\Util\Log\JUnit;
class MyJUnit extends Junit {
public function addWarning(Test $test, Warning $e, float $time): void {
$this->addError($test, $e, $time);
}
}
And register it as a listener in phpunit.xml:
<listeners>
<listener class="MyJUnit" file="MyJUnit.php">
<arguments>
<!--
Print the output to the file instead of stdout
which is the default.
-->
<string>junit.xml</string>
</arguments>
</listener>
</listeners>
Finally, go to Jenkins settings and add a JUnit job specifying the location of output file.
check the file name and import the
require_once 'ClassName.php';

PHPUnit Plugin in Netbeans 8.2 gives Fatal error: Class 'PHPUnit_Framework_TestSuite' not found when trying to run a test case

When I try to run PHPUnit in Netbeans I face this error:
Fatal error: Class 'PHPUnit_Framework_TestSuite' not found in C:\Users\julian\AppData\Roaming\NetBeans\8.2\phpunit\NetBeansSuite.php on line 63
Done.
This happens both in Netbeans and CLI.
I started debugging this problem by navigating to this directory: C:\Users\julian\AppData\Roaming\NetBeans\8.2\phpunit\.
That directory contained one file: NetBeansSuite.php. I opened it to look for clues, and saw this line:
class NetBeansSuite extends PHPUnit_Framework_TestSuite {
What I didn't see is any concrete PHPUnit_Framework_TestSuite class.
What's next is that the NetBeansSuite.php file doesn't have any include or require language constructs that may include the PHPUnit_Framework_TestSuite class.
So, in order to fix the fatal error problem I should include the PHPUnit_Framework_TestSuite in NetbeansSuite.php.
This is a problem because I'm not the author of NetbeansSuite.php.
On top of that the author of NetbeansSuite.php wrote this in the comment section:
<b>WARNING: User changes to this file should be avoided.</b>
I read further in the comments:
* Copyright 2010 Oracle and/or its affiliates. All rights reserved.
I guess the NetbeansSuite.php file is outdated.
Searching on the net brought me to this stackoverflow question:
Why, Fatal error: Class 'PHPUnit_Framework_TestCase' not found in ...?
They claim that using a namespaced version of PHPUnit_Framework_TestCase should fix the problem. So I did what they wrote.
I stubbornly changed NetBeansSuite.php.
Old code:
class NetBeansSuite extends PHPUnit_Framework_TestSuite {
New code:
require_once 'PHPUnit/Autoload.php';
use PHPUnit\Framework\TestCase;
class NetBeansSuite extends TestCase {
I tried to run the test case again, and this was the unfortunately result:
Fatal error: Declaration of CalculatorTest::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp(): void in C:\wamp64\www\test\CalculatorTest.php on line 97
In other words, it gave me a new problem.
My system:
Windows 10
WAMP
php 7.2.14
PHPUnit 8.0.6
Netbeans version 8.2 (Netbeans PHPUnit plugin installed through Tools > Plugins. Version: 0.26.2)
My question is: does anybody know how the NetBeansSuite.php file should be like with the system described above?
The setUp method in my test case:
protected function setUp()
{
$this->object = new Calculator;
}
Update: The Skeleton Generator project is abandoned.
See link: https://github.com/sebastianbergmann/phpunit-skeleton-generator
So in order to fix the Declaration of CalculatorTest::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp() error the corresponding return type declaration should be used in the test case.
// I added : void
protected function setUp(): void
{
$this->object = new Calculator;
}
// : void needs to be added in the tearDown method as well
protected function tearDown(): void
Unfortunately, this gave me new problems:
Warning: require_once(PHPUnit/Autoload.php): failed to open stream: No such file or directory in C:\wamp64\www\test\CalculatorTest.php on line 4
Fatal error: require_once(): Failed opening required 'PHPUnit/Autoload.php' (include_path='.;C:\php\pear') in C:\wamp64\www\test\CalculatorTest.php on line 4
I solved this by manually installing PEAR and creating a new "PHPUnit" directory in C:\php\PEAR. Then I created a new Autoload.php file. I filled the content of Autoload.php with a PSR-4 example file found at: https://www.php-fig.org/psr/psr-4/.
This solved the Autoload problem, but I faced a new problem during the execution of a test case.
C:\wamp64\www\test>phpunit CalculatorTest.php
PHPUnit 8.0.6 by Sebastian Bergmann and contributors.
Time: 170 ms, Memory: 10.00 MB
No tests executed!
It shows No tests executed! but I have 5 tests.
I'll make a new question for this.
Here it is: PHPUnit 8 installed on Windows through PHAR shows No tests are executed
Initially indeed you should update your namespaces since it has been changed in more recent versions of PHPUnit.
The error however indicates that your CalculatorTest::setUp() method is not compatible with the PHPUnit version. Could you maybe post that method here?
For the same issue, I directly changed the file "NetBeansSuite.php" (C:\Users\USERNAME\AppData\Roaming\NetBeans\8.2\phpunit) as following :
class NetBeansSuite extends \PHPUnit\Framework\TestSuite {
After that, CLI and Netbeans was working.

Selenium PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue()

I'm following examples from the book PHPUnit Essentials by Zdenek Machek and I'm on the section about functional tests using Selenium.
I already downloaded the server, the webdrivers and the firefox IDE.
The test class exported by Firefox IDE:
class SeleniumFirstTest extends PHPUnit_Extensions_Selenium2TestCase {
protected function setUp() {
$this->setBrowser('firefox');
$this->setHost('127.0.0.1');
$this->setPort(4444);
$this->setBrowserUrl('https://www.google.com.br/');
}
public function testCasephp()
{
$this->url("/?gws_rd=ssl");
$this->byId("lst-ib")->value("phpunit");
$this->byLinkText("Documentation")->click();
$this->byLinkText("13. PHPUnit and Selenium")->click();
$result = $this->byCssSelector("h1.title")->text();
$this->assertEquals("Chapter 13. PHPUnit and Selenium", $result);
}
}
When I try to run the tests in NetBeans I get the following output:
"C:\bin\phpunit.bat" "--colors" "--log-junit" "C:\Users\MARCOS~1.PRA\AppData\Local\Temp\nb-phpunit-log.xml" "--configuration" "C:\WebServer\Apache 2.2\htdocs\DataBaseTests\tests\phpunit.xml" "C:\Program Files\NetBeans 8.0.2\php\phpunit\NetBeansSuite.php" "--run=C:\WebServer\Apache 2.2\htdocs\DataBaseTests\tests"
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
Configuration read from C:\WebServer\Apache 2.2\htdocs\DataBaseTests\tests\phpunit.xml
E......
Time: 25.44 seconds, Memory: 5.75Mb
There was 1 error:
1) SeleniumFirstTest::testCasephp
Argument 1 passed to PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue() must be of the type array, null given, called in C:\WebServer\Apache 2.2\htdocs\DataBaseTests\vendor\phpunit\phpunit-selenium\PHPUnit\Extensions\Selenium2TestCase\Element\Accessor.php on line 136 and defined
C:\WebServer\Apache 2.2\htdocs\DataBaseTests\tests\Marco\Test\Functional\SeleniumFirstTest.php:26
C:\WebServer\Apache 2.2\htdocs\DataBaseTests\tests\Marco\Test\Functional\SeleniumFirstTest.php:26
C:\Dev\PHPUnitTest\vendor\phpunit\phpunit\src\TextUI\Command.php:152
C:\Dev\PHPUnitTest\vendor\phpunit\phpunit\src\TextUI\Command.php:104
FAILURES!
Tests: 7, Assertions: 14, Errors: 1.
Generating code coverage report in HTML format ...teste done
Done.
I can't understand why the test is failing, considering it passes when executed on the Firefox IDE.
May someone help me to understand this?
Thanks

why error_log generate a RuntimeException only with phpunit's --process-isolation

i had a few tests which code being tested outputed some error_log information (since i'm testing failures as well, this is expected)
e.g.
<?php
Class X {
function dosomething(){
error_log('did it');
return true;
}
}
and the test:
<?php
require_once 'X.php';
class xTest extends PHPUnit_Framework_TestCase {
public function testDo(){
$x = new X();
$this->assertTrue( $x->dosomething(), 'dosomething returns true');
}
}
which when run on php_unit without --process-isolation gives me a nice . and whatever i'm testing pass.
however, when run with --process-isolation i get:
1) test::a with data set #1 'a'
RuntimeException: did it
why is that happening? i'm stuck on version 3.4.12 (can't do much about it) but didn't find anything interesting in the changelog about that.
here's a sample session:
xxx$ phpunit xTest.php
PHPUnit 3.4.12 by Sebastian Bergmann.
did it
.
Time: 0 seconds, Memory: 4.50Mb
OK (1 test, 1 assertion)
shell return code: 0
xxx$ phpunit --process-isolation xTest.php
PHPUnit 3.4.12 by Sebastian Bergmann.
E
Time: 0 seconds, Memory: 4.50Mb
There was 1 error:
1) xTest::testDo
RuntimeException: did it
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
shell return code: 2
edit: i was searching for "phpunit runtimeexception error_log" and 5sec after submiting this it's already the top search result :( there's nothing about it out there.
but i came here to edit and say this:
adding $this->setExpectedException('RuntimeException'); does absolutely nothing to catch this. same outcome happens.
My guess is there is a difference between the error_log configuration in the outer and inner process. By default when running error_log() from the CLI it will be written to stderr and cause a test failure. What you need to do is work out why there is a difference. I would guess that you have some code that runs in the outer process that changes this configuration that is not getting run on the inner.

Categories