Different configurations for Unit and Integration Tests in PHPUnit - phpunit

I would like to have different configuration files for PHPUnit for my
Unit Tests: no database available, no cache, no everything
integration tests: everything is there
AND
to be able to execute these tests in PhpStorm all together or separated per file with automatically the right configuration.
There are several opportunities, which do not work for all needs:
Option 1:
Multiple phpunit.xml files
In PhpStorm can only set one PHPUnit default configuration, for executing a single test file, this will not work.
Option 2: Using a PHPUnit_Framework_BaseTestListener::startTestSuite($suite).
This works with a single phpunit.xml and if you are just executing the whole test suite, this works. But when you want to execute a single test file in PhpStorm, you do not have a $suite available and can not load the right configuration.
How do you handle different test configurations with PhpStorm?

Because there seems to be no offical possiblity on PHPStorm, I figured out a way by using a PHPUnit TestListener:
https://sebastianviereck.de/run-phpunit-unit-integrations-test-configurations-phpstorm/

PHPStorm can handle unit tests and integration tests in the same phpunit.xml file
Create two separate test suites in the same xml file. Each suite must have a distinct name in the name attribute.
Create two separate configurations for the tests
in PHPStorm (one for the unit tests and one for the integration tests) and indicate the same xml configuration file path for both tests
In the "Test Runner options" field, indicate the test suite name (the same as the one in the xml file) like this: --testsuite unit_tests
<testsuites>
<testsuite name="unit_tests">
<directory>/foo</directory>
</testsuite>
<testsuite name="integration_tests">
<directory>/bar</directory>
</testsuite>
</testsuites>
Once you have done that you can run unit tests and integration tests separately and still have them configured in the same xml file

Related

Grouping phpunit tests. Launching test from specified directory

I have a directory tests where I store all my tests.
Hierarchy of tests dirrectory
tests->
ApplicationTests->
IntegrationTests->
Factory->
Service->
UnitTests->
How can I make phpunit launch tests only from for example Service directory, instead of the whole tests directory? I read about #Groups, but I think that's not what I'm looking for and it would be best if I would not need to edit config files, but some how, do it from the command line.
Found a quite easy way, even with config editing.
phpunit.xml
See: The XML Configuration File Phpunit Docs and Organizing Tests Phpunit Docs<
<testsuite name="Service">
<directory>tests/IntegrationTests/Service</directory>
</testsuite>
Command line:
php ./vendor/bin/phpunit --testdox --testsuite Service

PhpStorm doesn't get the folder's configuration when running a single test method

I have a Laravel project with three test directories - Browser, Feature, and Unit.
In Run/Debug configurations I've configured the Feature and the Unit directories to use phpunit.xml while the Browser directory uses phpunit.e2e.xml. I've also created a default configuration for all tests which uses the phpunit.xml.
If I open a class that is in the Feature/Unit directories and run a single test method or the whole class, it picks the default configuration, but when I run a single test method in the Browser directory, it uses phpunit.xml instead of phpunit.e2e.xml.
If I select a directory and run tests, it picks the proper configuration, but when I open a class in the Browser directory, it doesn't
Why doesn't PhpStorm use the configuration of the Browser directory recursively? How can I handle this problem?
As far as I know PhpStorm has never had this functionality and I wouldn't count on them adding it either. It seems way too specific.
What you can do though, is specify the configuration file you want to use through the commandline.
See: https://phpunit.de/manual/6.5/en/textui.html#textui.clioptions
So your command would look something like this:
phpunit tests\Unit\SomeTest.php --configuration phpunit.xml
or
phpunit tests\Browser\SomeTest.php --configuration phpunit.e2e.xml

Configuring phpStorm and XML for phpUnit 7 (remote) Coverage

I'm playing for a week with phpUnit.
I'm slowly going forward with documentation at:
https://phpunit.readthedocs.io
At this point I'm at code Coverage. I've managed to generate small test --coverage-html (via console). I want everything to work via phpStorm.
I'm struggling with inclusion paths. I can see errors in console, but these aren't to helpful at all.
This is how my console output looks like:
This is the only place I use this file in
This is how folder structure for tested and displayed (in console) file looks like
|- dir:Boostrap
|- dir:Coverage
|- dir:Database
|- dir:Interfaces
|- dir:Methods
|---- file: BasicCalculations.php (line 3 inclusion)
|- dir:Tests
|---- file:DataDisplayingTest.php (file that I'm testing)
|---- dir:Data Providers
|-------- file:BasicCalculationDataProvider.php (line 4 inclusion)
What I've tried/What I've made so far
Cannot find PHPUnit in include path phpstorm (I'm not doing this via composer/vendor so this is not helping, my remote machine is for all the debugging, calculations etc).
PHPUnit test suite include path - this gave me idea to play around with bootstrap file, where I've included all the required files, but again this worked only via manually running tests in console - I want to make it work in phpStorm remotely.
PHPUnit's whitelist and blacklist seem to be ignored . At this point situation looks like this
without processUncoveredFilesFromWhitelist="true" I've got no inclusion error, but I got just more errors after that:
It looks like it's trying to work as console gets green for a moment and I've got the Coverage panel now, but I bet this errors shouldn't be there. I can't be sure If coverage report is being displayed correctly at all.
PHPUnit error "Failed to open stream: No such file or directory" - I've tried the DIR as You can see,
https://github.com/sebastianbergmann/phpunit/issues/1932 - this helped me a bit, now I know I can/have to import xml, and this way I don’t have to generate coverage report remotely via ssh
This is how my phpunit.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
cacheResult="true"
verbose="true">
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory>/var/www/html/phpUnit</directory>
</whitelist>
</filter>
<php>
<includePath>/var/www/html/phpUnit</includePath>
</php>
</phpunit>
I've played around with directory/incluedPath, tried variation like:
- /var/www/html/phpUnit
- /var/www/html/phpUnit/
- .
- ./
- <file>pointed/tested/file/here/</file>
I'm working with:
phpStorm
phpUnit 7.x Remotely
php 7.x Remotely
xdebug Remotely
To be more clear:
what am I doing wrong?
how can I deal with inclusions problems?
what is causing all this inclusion path problems?
I’ve manage to solve all the problems I had. I’ve used some of the informations provided in the links I’ve pointed above.
First of all
Include errors
PhpUnit xml uses directive includePath, which in my case looked like this:
<php>
<includePath>/var/www/html/phpUnit</includePath>
</php>
Generally at this point the problem is with… existence of includePath in xml file. This attribute changes the inclusion path.
So lets say that You got project structure like that:
- dir: Classes
–- dir: A
–-- file: A.php class: A (extends B)
–- dir: B
–-- file: B.pphp class: B
-file: index.php
So from the look of file A.php You would need to include B.php like that:
../B/B.php
Since the working directory is
/var/www/html/phpUnit/Classes/
But now since You’ve set up inclusion path to:
var/www/html/phpUnit
File A, tries to load file B from the perspective of phpUnit folder, and it’s kinda looking for file in:
var/www/html
Not having this directive is not solving the problem as phpUnit seems to use some other default path.
I’ve solved this problem by changing the way I include files in project:
Just instead using:
include_once '../Interfaces/BasicCalculationsInterface.php';
I’ve started doing it like this:
include_once __DIR__.'/../Interfaces/BasicCalculationsInterface.php';
This way:
Single files tests work fine
Project itself works fine
phpStorm detects methods, classes etc in included file
Group tests work well too
Writing file index.html permission denied
I’ve stumbled upon this problem as well. This actually is some kind of phpStorm issue, which I don’t know how to solve permanently but I’ve dealt with it for the xml file from which I can run all my tests.
Basically phpStorm added some default configurations for executed tests.
In menu go to
Run/Edit Configurations
Take a look at field Test Runner options.
In my case phpStorm added
--coverage-html /
Everything would be fine, but I use Ubuntu on laptop as remote host, and phpStorm tries this way to create files in / directory for which there is no writing permission. Changing this to some writeable folder or removing this line solved the problem.
And that’s all, this is how my xml file looks like at this point (just in case someone would like to have something to look at)
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
verbose="true">
<filter>
<whitelist addUncoveredFilesFromWhitelist="false">
<directory suffix=".php">/var/www/html/phpUnit</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="/var/www/html/phpunit/coverage.xml" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-html" target="/var/www/html/phpUnit/phpStormCoverageTest" lowUpperBound="35"
highLowerBound="70"/>
</logging>
<testsuites>
<testsuite name="allTests">
<directory suffix="Test.php">/var/www/html/phpUnit/Tests</directory>
</testsuite>
</testsuites>
</phpunit>
Preview of working html/phpStorm coverage

Excluding certain tests from loading in phpunit

Some of my testcases use a custom testing library. Also these testcases are very slow. So I would like to run them only in the build server and not in my local. I want to run the other tests locally.
Following is the directory structure. The ones inside the slow directory are the slow test cases that should be excluded.
/tests/unit-tests/test-1.php
/tests/unit-tests/test-2.php
/tests/unit-tests/slow/test-1.php
/tests/unit-tests/slow/test-2.php
/tests/unit-tests/foo/test-1.php
/tests/unit-tests/bar/test-2.php
I tried creating groups using #group annotation. This works, but the issue is that these test files are getting loaded (tests not executed though). Since they require the test library which is not installed locally, it is giving an error.
What is the best way to create the phpunit.xml configuration such that these slow tests are excluded (and not even loaded) by default and can be executed if needed?
There are 2 options:
In your phpunit.xml create 2 test suits - one for CI server and one for local development
<testsuites>
<testsuite name="all_tests">
<directory>tests/unit-tests/*</directory>
</testsuite>
<testsuite name="only_fast_tests">
<directory>tests/unit-tests/*</directory>
<!-- Exclude slow tests -->
<exclude>tests/unit-tests/slow</exclude>
</testsuite>
</testsuites>
So on CI server you can run
phpunit --testsuite all_tests
And locally
phpunit --testsuite only_fast_tests
Obviously, you can name test suites as you want.
I think preferable way is:
Create phpunit.xml.dist and configure default execution of phpunit (for CI server and all those who just cloned repository)
Modify phpunit.xml by configuring your local execution of phpunit
(by adding <exclude>tests/unit-tests/slow</exclude> to default
testsuite)
Exclude phpunit.xml from version control.
From the docs:
If phpunit.xml or phpunit.xml.dist (in that order) exist in the
current working directory and --configuration is not used, the
configuration will be automatically read from that file.
Some links:
The XML Configuration File. Test Suites
How to run a specific phpunit xml testsuite?

PHPUnit testing individually in Symfony

I would like to run some unit Tests individually with PHPUnit, but I have certain classes separated from the Tests, since I am using the symfony framework, and I group the Tests and the Classes in different folders.
I would like to run the Tests individually like this:
php phpunit.phar MyTest.php
The problem is that the test file uses the classes from the controllers, and phpunit doesnt seem to be able to import the needed classes for the test.
This is not a problem to run all the tests together, thanks to phpunit.xml but when I want to run them individualy, its a problem.
How could I fix this?
You have to point phpunit where you have your phpunit.xml config file (because it must know the autoloader for example). If you have default symfony 2 structure it will be in app directory, so just run your test like that (I assume that you are in project root path):
phpunit -c app/ --filter="concreteTestPattern" src/Acme/DemoBundle/Tests/MyTest.php
edit:
Above will run all tests which names match to the pattern: /.*concreteTestPattern.*/
You would use the --filter argument in your PHPUnit command string. This will only run tests that match the pattern given. If you pass only the complete name of the test that you want run, phpunit should only run that test.
If you have a data provider associated with the test and only want to run one test case, you can also filter that by using --filter <testName>::<testcase name>
PHPUnit can be set to execute using a configuration file.
In our Symfony2 project this file is located at app/phpunit.xml.dist.
As this file is suffixed with .dist, you need to copy its contents into a file called app/phpunit.xml.
If you are using a VCS such as Git, you should add the new app/phpunit.xml file to the VCS ignore list.
You will also notice the configuration is specifying the bootstrap file located at app/bootstrap.php.cache. This file is used by PHPUnit to get the testing environment setup.
We can execute this test by running the following command from the root directory of the project. The -c option specifies that PHPUnit should load its configuration from the app directory.
$ phpunit -c app

Resources