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!
Related
I want to get coverage.xml for CodeCov.
PHP 8.0.2
PHPUnit 9.5.2
Xdebug 3.0.2
My class. It's very simple, just practice for code coverage
src/Car.php
<?php
/**
* This class is for car.
*/
class Car
{
public function GetColor()
{
return 'Blue';
}
}
Test file.
tests/CarTest.php
<?php
include_once __DIR__ .'/../src/Car.php';
use PHPUnit\Framework\TestCase;
/**
* #coversDefaultClass Car
*/
class CarTest extends TestCase
{
/**
* #covers Car::GetColor
*/
public function testCarGoodColor(): void
{
$car = new Car();
$this->assertSame('Blue', $car->GetColor());
}
}
When I enter
./vendor/bin/phpunit tests/ --coverage-clover ./coverage.xml
I get this message:
PHPUnit 9.5.2 by Sebastian Bergmann and contributors.
Runtime: PHP 8.0.2 with Xdebug 3.0.2
Configuration: /Applications/CI-CD/phpunit.xml
. 1 / 1 (100%)
Time: 00:00.187, Memory: 8.00 MB
OK (1 test, 1 assertion)
Generating code coverage report in Clover XML format ... PHP Fatal error: Cannot declare
class Car, because the name is already in use in /Applications/CI-CD/src/Car.php on line 8
Fatal error: Cannot declare class Car, because the name is already in use in /Applications/CI-CD/src/Car.php on line 8
How to resolve this issue with classes?
Big thanks to LazyOne
Problem was with
include_once __DIR__ .'/
../src/Car.php';
I fix it with autoload.
Also, I had index.php in src/ and I add it to ignore for code coverage.
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';
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
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
I get phpunit and install it as this link using the simplest way for test purposes. I just download the phpunit.phar file, chmod & rename & move to /usr/local/bin
Then, I run phpunit --version, its ok.
I write a simple php test case.
class SimpleTest extends PHPUnit_Framework_TestCase {
public function testSomething(){
$this -> assertTrue(true);
}
}
In terminal , I go to my php class folder, and execute
phpunit --colors SimpleTest
Now I got the exceptions
PHP ReflectionException: Method suite does not exist
in phar:///usr/local/bin/phpunit/phpunit/Runner/BaseTestRunner.php on line 113
PHP Stack trace:
PHP 1. {main}() /usr/local/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main($exit = *uninitialized*)
/usr/local/bin/phpunit:612
PHP 3. PHPUnit_TextUI_Command->run($argv = array (
0 => '/usr/local/bin/phpunit',
1 => '--colors',
2 => 'SimpleTest.php'),
$exit = TRUE)
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:129
PHP 4. PHPUnit_Runner_BaseTestRunner->getTest(
$suiteClassName = 'SimpleTest',
$suiteClassFile = '/home/kevin/Workspace/php/laravel/app/tests/SimpleTest.php',
$suffixes = array (0 => 'Test.php', 1 => '.phpt'))
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:150
PHP 5. ReflectionClass->getMethod('suite')
phar:///usr/local/bin/phpunit/phpunit/Runner/BaseTestRunner.php:113
PHPUnit 3.7.27 by Sebastian Bergmann.
Anything is welcome, thanks .
It looks like this error comes from an xdebug setting.
The solution appears to be adding this line to your php.ini file (or changing your the existing value to 0):
xdebug.show_exception_trace = 0
Take a look at
PHPUnit ReflectionException Method suite does not exist and
Why does PHPUnit hide my xdebug backtrace? for more info.