How to run full directories in phpunit? - php

I have somewhat complex dir structure for my tests.
En example:
unitests
unitests/moduleA
unitests/moduleA/t1.php
unitests/moduleA/t2.php
unitests/moduleA/t3.php
unitests/moduleB
unitests/moduleB/t1.php
unitests/moduleB/t2.php
unitests/moduleB/t3.php
I might have deeper directory structure.
How would I run ALL the tests in one command?
(I tried phpunit unitests/*/* which ran only the first file found unitests/moduleA/t1.php)

You should use a configuration file, it will make things easier to run the tests in the future.
If you create a phpunit.xml file containing :
<phpunit>
<testsuites>
<testsuite name="Unit">
<directory>unitests/*</directory>
</testsuite>
</testsuites>
</phpunit>
and run phpunit, all tests should run.
You should also suffix all your classes with Test.
Also it's not a bad idea to create a test suite per sub-folder.

Related

How to use $_SERVER['DOCUMENT_ROOT'] with Phpunit

I am trying to set up Phpunit and across my whole project, $_SERVER['DOCUMENT_ROOT'] is used to link all files/functions/the connection etc. In my test class if I link the absolute path of my global_php_includes.php file (which is the parent file that contains more includes for everything else) then it gets an error every time $_SERVER['DOCUMENT_ROOT'] is called.
I'm very new to Phpunit, is there any way to solve this? I installed it using composer. Here is my xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<phpunit bootstrap="vendor/autoload.php" colors="true" verbose="true" stopOnFailure="true">
<testsuites>
<testsuite name="unit">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
Facing this issue, you can't do it (as far as I know).
If you launch phpunit through CLI, it's not use by the server directly, but with PHP, so you have to specify the absolute path (the same way that if you do a cron job).
I recommend you to use classes with you website to make it easier to use PHPUnit, but use absolute path for you project

phpunit no tests executed

I have a 'No tests executed' with phpunit..
This line works
$ phpunit install/InstallDbTest.php
...
<result expected>
...
$ cat suites/installtests.xml
<phpunit>
<testsuites>
<testsuite name="database">
<file>install/InstallDbTest.php</file>
</testsuite>
</testsuites>
</phpunit>
$ phpunit -c suites/installtests.xml
PHPUnit 4.7.4 by Sebastian Bergmann and contributors.
Time: 130 ms, Memory: 11.25Mb
No tests executed!
Does anyone can tell me what I am doing wrong ?
Thanks in advance!
You need to correct the path in your phpunit.xml.
It is trying to find the filesuites/install/InstallDbTest.php. Since the file doesn't exist, no tests are run and you get the message.
Change the configuration to the following:
<phpunit>
<testsuites>
<testsuite name="database">
<file>../install/InstallDbTest.php</file>
</testsuite>
</testsuites>
</phpunit>
File paths in phpunit.xml are all relative to the location of the xml file.
Maybe in the InstallDbTest.php file you are missing:
<?php
...
For those of you who you use a different bootstrap file than the Composer's autoload file, make sure you don't use one of your test case classes.
Indeed, PHPUnit (version 6.2 in my case) add to the running TestSuite all PHP files for which no class is loaded yet (see how it's done in the code). From the TestSuite::addTestFile($filename) method:
$classes = get_declared_classes();
$filename = Fileloader::checkAndLoad($filename);
$newClasses = \array_diff(\get_declared_classes(), $classes);
So if your class already belong to the get_declared_classes it will be ignored.
To summarize: don't use your test class before ;)

How to configure PHPUnit to test the whole vendor folder in a ZF2 application?

I'm developing a Zend Framework 2 application with a common folder structure, so that the folder /vendor contains all (project external) libraries. Setting up the unit testing environment I would like to be able to run all vendor tests. The folders structures are different depending on the library. Some packages have no tests at all.
A possible solution would be to create a test suite "vendor" and manually define there the paths to every single test folder, e.g.:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor/lib-foo/path/to/tests</directory>
<directory>../vendor/package-bar/path/to/tests</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
I don't like this solution. First of all because then I'd have to handle every package manually.
Another solution would be to define /vendor as test folder:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
Well, but then PHPUnit has to scan a lot of folders, that it doesn't need, and the tests will need much more time.
Is there a better solution, that would make possible to automate the process and avoid much manual configuration?
It would probably be difficult to run all PHPUnit vendor test suites with a single test run. One issue is that each of the different test suites might ship its own configuration file or even require a custom bootstrap configuration file. You cannot cover that when running all test suites with a single command.
I'd probably use some shell magic for this. Note that this example relies on the presence of a phpunit.xml(.dist) file in each of your 3rd party packages (for most libraries that's a reasonable assumption). You could even integrate this into your continuous integration process to test this continuously:
for FILE in $(find . -name 'phpunit.xml*') ; do
sh -c 'cd '$(dirname $FILE)' && composer install'
vendor/bin/phpunit -c $FILE
done

PHPUnit TestSuite Exclude

so I would like to exclude a directoy from my Testsuite just like this:
<testsuite name="PHPUnitWillKillMe">
<directory>src/*/Bundle/*/*Bundle/Tests</directory>
<exclude>src/*/Bundle/*/*Bundle/Tests/Controller/</exclude>
</testsuite>
Everything except for the Controllers should be tested.
The thing is, it does not work. PHPUnit still runs all the tests in src//Bundle//*Bundle/Tests/Controller/ when I run
phpunit --testsuite PHPUnitWillKillMe
Any idea?
Best Regards!
PHPUnit Version I tested this were 3.7.21 and 3.7.28.
I tested it on my Symfony demo project (the Bundles suggests that this is what you are using) and I have the same issue. It seems to be a combination of two problems. First, there is a known bug with running PHPUnit (PHPUnit 3.7.19) with the -c or --config option:
https://github.com/sebastianbergmann/phpunit/issues/928
When running it elsewhere and specifying the config file using --config, the exclude would however stop working.
Second, the exclude directive seems to ignore / fail when there is any globbing (*) in the path, so by removing the globbing, it worked for me:
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
<exclude>../src/Blah/MyBundle/Tests/Controller/</exclude>
</testsuite>
</testsuites>
It's the only way I found to exclude the Tests in MyBundle as required. The globbing did not work for the exclude. But then, it means you have to add as many exclude directives as there are folders you want to ignore.
Probable related gihub issue:
https://github.com/sebastianbergmann/phpunit/pull/573
[...] this fix lands in the 4.0 release as it breaks backwards compatibility.
Solution #1: remove any globbing in your paths
Solution #2: Upgrade to PHPUnit v4.* (not tested by myself, see comments, doesn't solve the problem of exclude paths with globbing)
Just had similar issue, phpunit has quite nice support for groups:
...
--filter <pattern> Filter which tests to run.
--group ... Only runs tests from the specified group(s).
--exclude-group ... Exclude tests from the specified group(s).
--list-groups List available test groups.
...
What you do is
/**
* #group nonRunnableGroupName
*/
public function testSomething()
{ /* test here */ }
And run test like
$ phpunit -c /src --exclude-group nonRunnableGroupName

How to test every module in my application phpunit - zend framework 2

I already made test for my application module and other module. They are working fine but i want to run all the test (application module and other module) toguether to generate clover report for jenkins. What should i do?? create another config file to invoke other config files??
---edit---
I have the same code for each module bootstrap.php and i want to use the same for each module to avoid code duplication. Rigth now i have two modules Application and Problem when i run phpunit it throws me this error:
**.PHP Fatal error: Class 'ProblemTest\Bootstrap' not found ....**
The test for the Application module works fine but the test for Problem module doesn't work for the namespace declaration in the phpunit_bootstrap.php file.
My Application test uses this declaration:
<?php
namespace ApplicationTest\Controller;
use ApplicationTest\Bootstrap; ....
My Problem tes uses this declaration:
<?php
namespace ProblemTest\Controller;
use ProblemTest\Bootstrap;
This is my phpunit.xml
<phpunit bootstrap="phpunit_bootstrap.php">
<testsuites>
<testsuite name="ALL">
<directory>module/Application/test</directory>
<directory>module/Problem/test</directory>
</testsuite>
</testsuites>
this is my phpunit_bootstrap.php
<?php
namespace ApplicationTest;
The problem that i have rigth now to run all the test toguether is how to include the same bootstrap for every test to avoid that exception.
You can make a testsuite to run a bunch of individual groups of tests all at once. In your phpunit.xml.dist file:
<phpunit bootstrap="phpunit_bootstrap.php">
<testsuites>
<testsuite name="all">
<directory>./</directory>
</testsuite>
<testsuite name="ALL">
<directory>/path/to/module1tests</directory>
<directory>/path/to/module2tests</directory>
<directory>/path/to/module3tests</directory>
<exclude>/path/to/module4tests</exclude>
</testsuite>
<testsuite name="module1only">
<directory>./module1tests</directory>
</testsuite>
</testsuites>
And then you can run it with: /path/to/phpunit --testsuite="ALL"
I can't comment yet so another solution to this issue can be found at zend framework 2 + phpunit + multiple modules + continuous integration If you don't want to go through naming each module independently.

Categories