How do I use a phpunit.xml file?

On the command line, everything works. A simple "phpunit" within my root directory reads the phpunit.xml config file and executes the tests only within the ./app/mysite/tests directory. However, same location in PHP does not, and it's even reading in the .xml file. What gives? Both sides are also using the same phpunit.phar file.

Here's expected output on Command Line:

PHPUnit 3.7.29-1-g0a32f05 by Sebastian Bergmann.

Configuration read from /var/www/track/phpunit.xml

.......

Time: 108 ms, Memory: 4.75Mb

OK (7 tests, 11 assertions)

[root@gizmo track]# ls -l phpun*

-rw-rw-rw-. 1 nobody apache 408 Jan 22 16:03 phpunit.xml

Within my IDE, things aren't working as expected. I ran "Run 'trunk-track'" via right-click to produce these errors.

phpunit-error.png

13 comments

Hi there,

I have no clue at all what kind of Run/Debug Configuration you have created by rigth clicking (BTW -- right clicking on what?).

Therefore -- please show screenshot of Run/Debug Configuration you have used as well as IDE settings for PHPUnit. Possibly it is not configured properly -- the Test Scope must be set to "Defined in configuration file".


Some related articles:

0

Here's a screen shot of the configuration setting:
phpunit-test-config.png
> "Defined in configuration file".


That's what I didn't have checked. I assumed it would have picked up the default settings automatically. I was in the PHP Storm documentation before posting. I didn't anything mentioned about requiring this to be selected, nor did I find anything about using a phpunit.xml config and boostrap file. What did I miss? I was here, in the help docs: https://www.jetbrains.com/phpstorm/webhelp/creating-run-debug-configuration-for-tests.html

However, fixing that, I'm still getting errors. It's not picking up the autoload.php: it can't find my Controller class I'm testing:

phpunit-error2.png

Thanks for the links. I'm watching the Webinar now with Michelangelo!

(PS: Maybe it is finding the autoload, but it's not finding the class. Oddly enough, in the terminal, the entire Controller is actually displayed. So it's clearly seeing it, somehow)

0

I do not know, really. It's too little info for me to say anything concrete (need actual project to try myself) -- only guessing.

1) PhpStorm uses helper script (ide_phpunit.php) to execute PHPUnit tests (for integration purposes -- to track execution progress etc). Maybe your phar version is not compatible with that script. What's PHPUnit version do you have there? Should work OK with 3.7 (worked for me when I was testing it about 2-3 months ago on *simple* project) but may have problems with 3.8.

2) Try setting up correct working directory (set it to project root).

3) Since it's unable to find classes (autoload failure??) then try debugging instead of just running (setup breakpoints in autoload file) and see how it will handle it -- maybe it misses something (due to misconfiguration/whatever).

0

> http://blog.jetbrains.com/phpstorm/2013/04/recording-of-the-webinar-quality-assurance-for-php-projects-using-phpstorm-with-michelangelo-van-dam/

He doesn't select "Defined in configuration file."  All he did was set the default configuration file, hit Okay, and ran his tests successfully. Right at 21:39, he selects the default configuration file. Hits okay, and hits 'Run'. The console immediately says it's reading from the config file. His options are: 'Test Scape: Directory'. Directory selected is 'test' directory. And he's relying upon the default phpunit.xml setting for the project. He does not select an alternate configuration file. His setup is exactly like my setup in the first image.

0

As far as my tests show: if I do not provide path to phpunit.xml at all, it will NOT be picked up automatically (when running from IDE, of course).

My bootstrap file is declared in phpunit.xml (same folder) -- I do not provide it separately, and it works. But if I do not provide phpunit.xml nothing gets found (classes, I mean).

He doesn't select "Defined in configuration file."

My impression was that you want to execute only tests that are defined in that phpunit.xml file and not all tests in a folder. If it's not the case (and I have misunderstood this moment -- sorry about this) then you should switch Test Scope back to Directory (or whatever else is required).

But still -- if you have specific settings you should specify what phpunit.xml to use.

His setup is exactly like my setup in the first image.


In such case the only (teh most obvious) problem I can think of -- is the actual autoloader. That;s why I have suggested to debug it (it may help).

This is one of my setups -- works just fine for me:
screen01.png

0

It's interesting. I put the configuration back to directory, and pointed it to my 'tests' directory. The config file and autoloader are loaded just fine. I trace the tests, and see my class is successfully being included, but It's still coming back with MyNs\Tracking\TrackController class not found. Trace takes me to Composer\Autoload\Classloader::loadClass line 271. $file is: D:\Documents\Source\trunk-track/app/pkg-name/src\TrackController.php. "include $file" successfully loads the file. loadClass() returns TRUE, and php then fails to "MyNs\Tracking\TrackController" class now found.

One additional variable:
- My namespace is defined using PSR-4 standards. This shouldn't be a problem since it's composer that qualifies the namespace and include. But could it be something related to PhpStorm's tracing that's breaking?

You can see from this shot, there is definitely something strange going on:

phpunit-debug.png

And here is a shot of my composer.json, defining PSR-4 Namespace:

composer-json.png

0
But could it be something related to PhpStorm's tracing that's breaking?


It should not -- as it's PHP (and Composer) who are loading the class and PHPUnit that reports that problem. Tracing is not involved until exception raised AFAIK.

Few more ideas:
1) Add something like $result = class_exists($class, false); into Composer code (just before return statement) -- this is to check if class was actually loaded -- check value of $result in debugger if it has true or false when it loads that problematic class -- this is just to verify it.

2) From your screenshot I see that you have PHPUnit installed via Composer but yet you are using PHAR version of it...

My suggestion: in "Settings | PHP | PHPUnit" choose "Use custom loader" and point to autoload functionality. Obviously, "Default bootstrap file" should be no longer required in such case (as it's the same autoloader.php as far as I understand)

0

1) Add something like $result = class_exists($class, false); into Composer code (just before return statement) -- this is to check if class was actually loaded -- check value of $result in debugger if it has true or false when it loads that problematic class -- this is just to verify it.


Interestingly, it comes back as false. I changed the 'include' to a 'require' and the script still runs successfully. The script works just fine on the command line, so it's not a mistype in the classname or namespace. As a test, I changed the namespace, and the command line errored out, as expected.

2) From your screenshot I see that you have PHPUnit installed via Composer but yet you are using PHAR version of it...

My suggestion: in "Settings | PHP | PHPUnit" choose "Use custom loader" and point to autoload functionality. Obviously, "Default bootstrap file" should be no longer required in such case (as it's the same autoloader.php as far as I understand)


I went both directions. First tried this: no change. Then I just took out the composer requriement (since I perfer not to have it as part of my deployment), and the same issue. And, again, everything is still functions as expected on the command line.

0

Very interesting indeed. To bad I do not know what else can be done here.

My last though: try to instantiate that class (and inspect it's properties) as soon as it was "loaded" (in the loader, instead of that previous check -- wrap it into try-catch if desired). Let's see if it was loaded or not this way.

Also -- instead of relying on autoload -- replace the code where it includes the file by direct include with full path to the class (make it all conditional, of course -- all classes are loaded normally and that one will be loaded "directly"). See if class will be found that way.

At very least you will be able to make some decision about it and what to do next. If you will have some time and desire to create some very basic project that could reproduce the problem -- you could then submit bug report ticket and hopefully they will fix it soon (if the issue actually is on PhpStorm side)

P.S.
If you can -- try this project on another computer (but create it from scratch -- do not copy .idea subfolder) -- maybe something in this installation interferes with executing PHPUnit tests (try with all 3rd party plugins disabled).

0

I think I discovered an issue: it would seem require isn't interpreting my PHP files... require is acting like a print dump (I've always wondered why my configuration file is dumping in the console windows).

Have you seen such a thing? I do a require on a file, and instead of interpreting (parsing) the file, it's echo'd to the screen? It's sent to STDOUT, not STDERR.

I ran a test:

        $test = require('app/config/app.test.php');
        var_dump(['test' => $test]);


Added to my Test class. The output is:

<? return array_merge(require('app.php'), [     "environment" => "testing", ]);array(1) {   'test' =>   int(1) }


It never even interpreted the PHP code?! This is why it's failing. For some reason, my PHP binary, on windows, is treating "require" as an "echo." ...  I've tried this with php 5.5.8 and php 5.4.24... maybe it's a php.ini setting I don't know about (I did copy the same ini between binaries).

0

Replace <? by full tag: <?php and try again.

...or check your php.ini

short_open_tag = Off
(must be "On" if you want to use <? )

P.S.
For better portability always use full <?php opening tag.

0

Oh hell. I found the problem ... damn PHP: short_tags. It's OFF by default on Windows ini, but ON by default for 5.5 on *nix systems, which explains why it worked on Linux but not Windows.

I've enabled short_tags, and it's now functional. :)

Actually, think I'll turn it off on by systems and fix all the code. Sorry for the confusion. It's all going well now. Owie!

Cheers!

0

Hi! That's exactly what I discoverd, too. And going with your suggestion. :)

Thanks!

0

Please sign in to leave a comment.