When I activate Xdebug and run a PHPUnit unittest this error occurs: ❌
Warning: assert(): assert($iterator instanceof FilterIterator) failed in [...]/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php on line 57
[... some stack trace information ...]
Return value of PHPUnit\Runner\Filter\Factory::factory() must be an instance of FilterIterator, instance of PHPUnit\Framework\TestSuiteIterator returned
I'm using
PHPUnit 9.5.6 by Sebastian Bergmann and contributors.
Runtime: PHP 7.4.21 with Xdebug 2.8.0
The PHPUnit execution call (clued together with PhpStorm) looks like:
/usr/bin/php74.bin.cli
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so
-dxdebug.collect_params=5
-dxdebug.profiler_enable=on
-dxdebug.auto_trace=1 -dxdebug.trace_format=1
-dxdebug.collect_return=1 -ddisplay_errors=1
-ddisplay_startup_errors=1 -derror_reporting=E_ALL
-dmemory_limit=512M
[...]/vendor/phpunit/phpunit/phpunit
--coverage-filter [...]/src/
--bootstrap [...]/utils/unittest/bootstrap.php
--configuration [...]/utils/unittest/phpunit.xml
--filter "/(BasicsTest::testReturnBytes)( .*)?$/"
--test-suffix BasicsTest.php [...]/utils/unittest/basics --teamcity
Calling a simple php script with Xdebug activated works well. ✔️
/usr/bin/php74.bin.cli
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so
-dxdebug.collect_params=5
-dxdebug.profiler_enable=on -dxdebug.auto_trace=1
-dxdebug.trace_format=1 -dxdebug.collect_return=1
-ddisplay_errors=1 -ddisplay_startup_errors=1
-derror_reporting=E_ALL -dmemory_limit=512M ./test.php
Calling the unittests without Xdebug activated works well. ✔️
/usr/bin/php74.bin.cli
-dallow_url_fopen=1
[...]/vendor/phpunit/phpunit/phpunit
--no-coverage
--bootstrap [...]/utils/unittest/bootstrap.php
--configuration [...]/utils/unittest/phpunit.xml
--filter "/(BasicsTest::testReturnBytes)( .*)?$/"
--test-suffix BasicsTest.php [...]/utils/unittest/basics --teamcity
My phpunit.xml
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
bootstrap="bootstrap.php"
colors="true"
verbose="true">
<coverage>
<include>
<directory suffix=".php">../../../src/*</directory>
<directory suffix=".php">../../../some other dirs/*</directory>
</include>
<exclude>
<directory suffix=".php">../../../some other dirs/*</directory>
</exclude>
<report>
<html outputDirectory="./x_testresults" lowUpperBound="35" highLowerBound="70"/>
</report>
</coverage>
<php>
<ini name="allow_url_fopen" value="On"/>
<ini name="memory_limit" value="5G"/>
<ini name="include_path" value="."/>
</php>
</phpunit>
The unittest
<?php
declare(strict_types = 1);
class BasicsTest extends PHPUnit\Framework\TestCase
{
function testReturnBytes(): void {
$this->assertSame(1, 1);
}
}
The docs say in https://phpunit.readthedocs.io/en/9.5/code-coverage-analysis.html#including-files that
It is mandatory to configure a filter for telling PHPUnit which source code files to include in the code coverage report. This can either be done using the --coverage-filter command line option or via the configuration file (see The Element).
This is what I did, see above. Also without setting a --coverage-filter parameter PHPUnit complains about missing filter information, so I added it.
For me it feels like the issue is related to the --coverage-filter parameter. The error message (see first code paragraph) says FilterIterator should be instance of PHPUnit\Framework\TestSuiteIterator but I don't know where to adjust this.
I found some mistakes in my setup and I found a kind of workaround to get the tests to be running with Xdebug.
The mistakes:
the includes and excludes tags in the phpunit.xml had wrong relative paths
the settings "-dxdebug.auto_trace=1" for xdebug on the command line command were outdated, see docs. Actually its strange that the test.php did run well.
The workaround:
set a testsuite to "." in the phpunit.xml and call it via --testsuite default
set a "#group dummy" to the specific class I want to test and call it via --group dummy to just call that test.
The testsuite setting in phpunit.xml in detail:
<testsuites>
<testsuite name="default">
<directory>./</directory>
</testsuite>
</testsuites>
The commandline call now:
/usr/bin/php74.bin.cli
-dzend_extension=/usr/local/php74/lib/php/extensions/xdebug.so
-dxdebug.collect_params=5
-dxdebug.profiler_enable=on
-dxdebug.trace_format=1
-dxdebug.collect_return=1
../../vendor/bin/phpunit
--group no-db
--verbose
--debug
--testsuite default
--group dummy
I have configuration that tests my localhost API succesfully in PhpStorm using PHPUnit. Also I can stop on breakpoints but only inside my TestCase classes.
I need to stop on breakpoints that are set inside logic that are tested, but it does not stop there.
Testing command:
/usr/bin/php -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=127.0.0.1 /foo/vendors/composer/phpunit/phpunit/phpunit --configuration /foo/_stuff/phpunit/config-api2.xml --teamcity
My config xml:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="../../foo/tests/app_test_case.php"
colors="true"
stopOnFailure="false"
>
<testsuites>
<testsuite name="foo">
<file>../../foo.php</file>
</testsuite>
Added to php.ini:
xdebug.remote_autostart = 1
Added to requested route:
?XDEBUG_SESSION_START=PHPSTORM
And added cookie in index.php:
header('Cookie: XDEBUG_SESSION=PHPSTORM');
Yes, you can.
The question here is how you are going to start a debug session for those API calls.
The most usual way would be adding xdebug.remote_autostart=1 to php.ini for the interpreter running the calls, so that a debug session would start for every single PHP call, API or not.
If you are not happy with it, you can add the XDEBUG_SESSION_START GET-parameter to HTTP requests of the calls, but that would obviously require code modification.
I'm using Symfony 2, PHPUnit 3.7.10 and PhpStorm 5.0.4.
I have a class MyTestListener (implements PHPUnit_Framework_TestListener) in the namespace Acme\DemoBundle\Tests.
When I call phpunit from CLI with vendor/bin/phpunit.bat -c app/
The listener work, the test is successful.
I found this: PHPUnit, PHPUnit_Framework_TestListener, Netbeans and the PHPUnit xml config but it seems to be another problem.
But when I start the test in PhpStorm the, the listener does not load, some objects should be injected into an abstract test class, which are null in this case. I also notices, that when I debug with a breakpoint in the MyTestListener class the debugger doesn't stop in this class, others breakpoints work fine.
the phpunit.xml entry:
<listeners>
<listener class="Acme\DemoBundle\Tests\MyTestListener" file="../src/Acme/DemoBundle/Tests/MyTestListener.php">
</listener>
</listeners>
I also try to add a empty element, it doesn't help.
In my Run/Debug Configuration of PhpStorm I specify phpunit.xml and the bootstrap file.
I also add this option for the Command Line/Interpreter: -d auto_prepend_file=vendor/autoload.php
The listener configuration in phpunit.xml seems to be parsed, but not work. When I change the class name to an invalid file/class, I get an error, that the file can't open the stream. I also try to use a absolute file path or change the slashes into backslashes, nothing works.
What a shame... I found my own error
I do all tests from CLI, but in PhpStorm only one test class, so the suite name was different and in my listener class I do the stuff only if the suite name match:
if ($suite->getName() == "db-tests") {...}
So the solution was to extends the expression to
$name = $suite->getName();
if ($name == "db-tests" ||
strpos($name, 'Acme\DemoBundle\Tests\Database') !== false) {...}
I currently have a problem that I have to work around in legacy code to get our interaction with a PHP Extension to work properly (Singleton Testing Question).
As such, I do not want to execute this code when running our normal production code with the application. Therefore, I need to check in regular PHP code if the code being executed is being executed as part of a test or not.
Any suggestions on how to determine this? I thought about a defined variable tied to the presence of the test files themselves (we do not ship the tests to customers) but our developers need the Extension to work normally, while the CI server needs to run the tests.
Would a Global set in the PHPUnit.xml file be recommended? Other thoughts?
An alternative approach is to set a constant in the PHP section of your phpunit.xml.*:
<php>
<const name="PHPUNIT_YOURAPPLICATION_TESTSUITE" value="true"/>
</php>
In your PHP application, you might then use the following check:
if (defined('PHPUNIT_YOURAPPLICATION_TESTSUITE') && PHPUNIT_YOURAPPLICATION_TESTSUITE)
{
echo 'TestSuite running!';
}
Define a constant in your PHPUnit bootstrap.php file. This is executed before loading or running any tests. This shouldn't impact developers running the application normally--just the unit tests.
If you're using Laravel than use App::runningUnitTests()
You could check the $argv different ways.
if(PHP_SAPI == 'cli') {
if(strpos($_SERVER['argv'][0], 'phpunit') !== FALSE) { ... }
// or
if($_SERVER['argv'][0] == '/usr/bin/phpunit') { ... }
}
Use PHPUnit Constants
You can either define constant, but that requires your work, no typos and it's not generic. How to do it better?
PHPUnit defines 2 constants by itself:
if (! defined('PHPUNIT_COMPOSER_INSTALL') && ! defined('__PHPUNIT_PHAR__')) {
// is not PHPUnit run
return;
}
// is PHPUnit
Sorry for another 'phpunit doesn't work' question. It used to work for years now. Today I reinstalled PEAR and phpunit for reasons not connected to this problem. Now when I run phpunit as I usually did. Nothing happens. The cli just shows me a new line, no output whatsoever.
Has anyone encountered this problem or has an idea what could have caused it.
PHPUnit Version: 3.5.15
PEAR Version: 1.9.4
PHP Version: 5.3.8
Windows 7
I'm on OSX and MAMP. To get error messages I had to adjust the following entries in php.ini:
display_errors = On
display_startup_errors = On
Please not that this has to go into /Applications/MAMP/bin/php/php5.3.6/conf/php.ini .
For future reference, for those who are facing any problem with PHPUnit, and PHPUnit is failing silently, just add this three lines inside phpunit.xml:
<phpunit ....... >
...
...
<php>
<ini name="display_errors" value="true"/>
</php>
</phpunit>
After that run the tests again, and now you can see why PHPUnit is failing,
AND ... ENJOY UNIT TESTING :)
I know the orignal poster's question is already answered, but just for any people searching in the future: one thing that can cause PHPUnit to fail silently (i.e. it just stops running tests without telling you why) is that it has an error handler that it set up before each test run, which is intended to capture errors and display them at the end of the test run. The problem is that certain errors halt execution of the whole test run.
What I generally do when this happens, as a first step, is reset the error handler to something that will immediately output the error message. In my base test class I have a method called setVerboseErrorHandler, which I'll call at the top of the test (or in setUp) when this happens. The below requires php 5.3 or higher (due to the closure), so if you're on 5.2 or lower you can make it a regular function.
protected function setVerboseErrorHandler()
{
$handler = function($errorNumber, $errorString, $errorFile, $errorLine) {
echo "
ERROR INFO
Message: $errorString
File: $errorFile
Line: $errorLine
";
};
set_error_handler($handler);
}
Create the simplest test class you can without a bootstrap.php or phpunit.xml to first verify that your new installation works. PHPUnit will stop without any message if it cannot instantiate all of the test cases--one for each test method and data provider--before running any tests.
You have already figured out how to get it to work, but my solution was a little different.
First thing you can do is check the exit status. If it's not 0, then PHP exited and because of the INI configuration settings set, none of the PHP error messages were outputted. What I did was to enable the "display_errors" INI setting, and set "error_reporting" to E_ALL. I was then able to identify errors such as PHP not being able to parse a certain script. Once I fixed that, PHPUnit ran properly.
I managed to spectacularly paint myself in a corner with a custom "fatal error handler" that in certain rare conditions turned out to output nothing. Those conditions, in accordance with Murphy's Law, materialized once I had forgotten the handler was in place.
Since it wasn't really a "PHPunit problem", none of the other answers helped [although #David's problem was at the bottom the same thing], even though the symptoms were the same - phpunit terminating with no output, no errors, no log and no clue.
In the end I had to resort to a step-by-step tracing of the whole test suite by adding this in the bootstrap code:
register_shutdown_function(function() {
foreach ($GLOBALS['lastStack'] as $i => $frame) {
print "{$i}. {$frame['file']} +{$frame['line']} in function {$frame['function']}\n";
}
});
register_tick_function(function() {
$GLOBALS['lastStack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 8);
});
declare(ticks=1);
If anyone ever manages to do worse than this, and somehow block stdout as well, this modification should work:
register_shutdown_function(function() {
$fp = fopen("/tmp/path-to-debugfile.txt", "w");
foreach ($GLOBALS['lastStack'] as $i => $frame) {
fwrite($fp, "{$i}. {$frame['file']} +{$frame['line']} in function {$frame['function']}\n");
}
fclose($fp);
});
an old thread this one, but one I stumbled across when having the same problem.
I had the same problem, nothing being returned to console including print, print_r, echo etc.
solved it by using --stderr as a test-runner option.
Check that you haven't written any logic into your code that just dies, with no output. For example,
<?php
if (!array_key_exists('SERVER_NAME', $_SERVER)) {
die();
}
This was exactly my case; I'd made some assumptions about the environment which were correct when running the code via Apache, but weren't fulfilled when running from CLI and the code did not echo any output.
PHPUnit tried to include the bootstrap file before giving the usual init output, but died during the bootstrapping proccess, hence exiting with status 0 and no output.
If when you run from command line a recent version of phpunit like this
> php phpunit
or
> ./phpunit
or
> php ./phpunit.phar
or
> ./phpunit.phar
And you immediatly return to the prompt with no messages, this is probably due to a "suhosin secutiry" setup.
phpunit is now a "phar" package including all libraries. To be able to run such file when php has the suhosin security module enabled, you must first set this
suhosin.executor.include.whitelist = phar
into you php.ini file (for example, with debian/ubuntu, you may have to edit file /etc/php5/conf.d/suhosin.ini
i tried everything here, but nothing worked until i tried phpunit --no-configuration simpletest.php. that finally gave me some output, which implies that my phpunit.xml.dist file is broken. (i'll come back and update this once i debug it.)
the contents of simpletest.php are below, but any test file should work.
<?php
use PHPUnit\Framework\TestCase;
final class FooTest extends TestCase
{
public function testFoo()
{
$this->assertEquals('x', 'y');
}
}
Check if the phpunit you're running and the one you installed are the same:
$ pear list phpunit/phpunit
...
script /path/to/phpunit
...
Try to execute exactly that phpunit with the full path.
Then check your PATH variable and see if the correct directory is in it. If not, fix that.
If that does not help, use write something into the phpunit executable, e.g. "echo 123;" and run phpunit. Check if you see that.
For me the conflict was with Xdebug's directive
xdebug.remote_enable=1
If you are using composer, check to make sure your included PHP files are not ending the code executions. The same goes for when you included certain PHP files explicitly.
In my case, I was working on a WordPress plugin and one of the PHP files I included directly in composer.json (which I don't want to load through PSR-4 because WordPress's coding standards don't support it yet) had this code on top;
if (!defined('ABSPATH')) {
exit(); // exit if accessed directly
}
And since ABSPATH will not be defined when I run the tests directly, the code was exiting.
This is because, since I told Composer to always load these files each time, this part of the code will execute, while the other files included though autoload PSR will load on demand.
So check to make sure any of the files you included are not stopping the code execution. If it happens, then even when you run phpunit --info the code will still exit and you won't see any output.
I was facing a seems problem. I could run phpunit from root directory but not from anywhere else. so I put the "--configuration" tag, and point it to my xml configuration.
$ ./<path_to_phpunit>phpunit --configuration <path_to_phpunitxml>/phpunit.xml
The path to phpunit is optinal, I used it because I installed locally by composer.
In /composer/vendor/phpunit/phpunit/src/TextUI/Command.php in main() function in catch (Throwable $t) {} block var_dump (echo / print_r) exception. If an exception exists, you, probably, will solve the current problem.