PHPUnit load test suite with recursive directory expression - phpunit

I am trying to define my phpunit.xml configuration with a custom test suite, which loads all Unit tests in desired folder recursively.
Folder path examples:
tests/path/Unit/MyTest.php
tests/path/path/Unit/MyTest.php
tests/path/path/path/Unit/MyTest.php
tests/path/path/path/path/Unit/MyTest.php
...
tests/{.../}/Unit/MyTest.php
I can define my suite like this:
<testsuites>
<testsuite name="Project Unit Test Suite">
<directory>tests/*/Unit</directory>
<directory>tests/*/*/Unit</directory>
<directory>tests/*/*/*/Unit</directory>
<directory>tests/*/*/*/*/Unit</directory>
...
</testsuite>
</testsuites>
Is there a way to iterate over all sub-folders that my expression would be only a single line?

I should use ** in this case. I'd try to name directories the same inside different sub-directories, so that ** would work everywhere.
<?xml version="1.0"?>
<phpunit colors="true" backupGlobals="false">
<testsuites>
<testsuite name="Test Suite">
<directory>tests</directory>
<exclude>**/Functional</exclude>
</testsuite>
</testsuites>
</phpunit>
or if you'd rather include things:
<?xml version="1.0"?>
<phpunit colors="true" backupGlobals="false">
<testsuites>
<testsuite name="Test Suite">
<directory>**/Unit</directory>
<exclude>*</exclude>
</testsuite>
</testsuites>
</phpunit>

Related

Code coverage report is not generating

When run command phpunit --bootstrap="TestHelper.php" --coverage-clover coverage.xml --whitelist="../../../" --debug --log-junit result.xml ./
It generates result.xml but console get stuck after this line.
Generating code coverage report in Clover XML format ...
Note : I already checked previous quetion on stackoverflow.
My phpunit.xml :
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./TestHelper.php"
backupGlobals="false"
backupStaticAttributes="false"
verbose="true"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true">
<testsuite name="Phalcon - Testsuite">
<directory>./</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="false">
<directory suffix=".php">../app/repositories/Account</directory>
<directory suffix=".php">../app/repositories/Call</directory>
<directory suffix=".php">../app/repositories/Credit</directory>
<directory suffix=".php">../app/repositories/User</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="./coverage.xml"/>
<log type="junit" target="./results.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>

Phpunit starts all the tests or not starts all the tests, ignoring the config

My project contains 2 packages, and I want to run tests in only one of them. Used symfony 3.3 and phpunit 6.3.0
phpunit.xml.dist
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="./src/CoreBundle/Tests/autoloadWithIsolatedDatabase.php"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_CLASS" value="AppKernel" />
</php>
<testsuites>
<testsuite name="App">
<directory>src/AppBundle/Tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
<exclude>
<directory>src/*Bundle/Resources</directory>
<directory>src/*Bundle/Tests</directory>
<directory>src/*/*Bundle/Resources</directory>
<directory>src/*/*Bundle/Tests</directory>
<directory>src/*/Bundle/*Bundle/Resources</directory>
<directory>src/*/Bundle/*Bundle/Tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
And structure of the project
This configuration will run all the tests from AppBundle and CoreBundle (in the second there are no tests), and if you change
<directory>src/AppBundle/Tests</directory>
to
<directory>src/CoreBundle/Tests</directory>
then there will be no tests at all. I can not understand what's wrong
Let's start of by how your phpunit.xml.dist is configured. You have one test suite defined:
<testsuites>
<testsuite name="App">
<directory>src/AppBundle/Tests</directory>
</testsuite>
</testsuites>
This is the place phpunit will look into for tests. They have to conform to the usual conventions like having a file name ending in Test and each test method must be prefixed with a test.
Also from your screenshot I can gather that you have a top level tests/ folder (right next to app/, src/, etc.). This is probably where your other tests are placed in.
The second folder is where you should also place your tests from the AppBundle if you follow the best practices: https://symfony.com/doc/current/best_practices/tests.html
I think this was established sometime during the 3.x release cycle.
In theory you should be able to copy src/AppBundle/Tests to tests/AppBundle and hopefully everything still works. Now you can update your test suite configuration to:
<testsuites>
<testsuite name="App">
<directory>tests/</directory>
</testsuite>
</testsuites>
Your filter can stay in place as src/CoreBundle/Tests does not actually contain test-classes, only helpers used for tests.
Now that you have all tests in one big tests folder separated by bundle you might want to do a search on this folder for classes extending PHPUnit_Framework_TestCase. Since PHPUnit 6.0 introduced namespaces those need to be updated with PHPUnit\Framework\TestCase otherwise PHPUnit will ignore those tests.

How to run multiple PHPUnit test suites from command line?

If you have multiple test suites configured in phpunit.xml how do you run more than one test suite but not all of them from the command line?
phpunit.xml
<?xml version="1.0" encoding="utf-8"?>
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="true"
bootstrap="tests/bootstrap.php">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">tests/unit</directory>
</testsuite>
<testsuite name="Integration">
<directory suffix="Test.php">tests/integration</directory>
</testsuite>
<testsuite name="Acceptance">
<directory suffix="Test.php">tests/acceptance</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-html" target="build/coverage"/>
<log type="testdox-html" target="build/requirements.html"/>
</logging>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
example
phpunit --testsuite Unit|Integration but not Acceptance
Since PHPUnit 6.0 you can specify a comma delimited list of suites:
--testsuite suite1,suite2
Original answer for versions < PHPUnit 6.0
It doesn't work as you expect it to i.e. (where <pattern> is not an actual pattern):
--testsuite <pattern> Filter which testsuite to run.
You can choose a test suite to run but you can't use a pattern to filter which ones to run.
A better description would be --testsuite <name> Which testsuite to run.
Issue report https://github.com/sebastianbergmann/phpunit/issues/2273, which was fixed in version 6.0.

Running tests only found in test folder

Here is my phpunit.xml:
<phpunit bootstrap="test/bootstrap.php"
colors="true">
<testsuites>
<testsuite name="MageScan Unit Tests">
<directory>test</directory>
</testsuite>
</testsuites>
</phpunit>
And my project structure
$ find src test -type f
src/bootstrap.php
src/MageScan/Application.php
src/MageScan/Command/Scan/Command.php
src/MageScan/Command/Scan/MagentoVersion.php
src/MageScan/PHPUnit/TestCase.php
test/bootstrap.php
test/MageScan/Command/Scan/MagentoVersionTest.php
When I run phpunit I get the error
1) Warning
No tests found in class "MageScan\PHPUnit\TestCase".
Why is it looking for tests in this class? Based on my testsuite configuration it should only be running tests in the test folder.

PHPUnit: No test executed with a seemingly good config file

I get the message no tests executed when i try to do
phpunit
or
phpunit -c phpunit.xml
on the other hand, if i do
phpunit -c phpunit.xml ./tests
It works. But this is a problem considering that some tool that I'm using does not handle this well.
Directory structur
code
tests/
phpunit.xml
autoloader.php
And here is the config file
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
bootstrap="./tests/bootstrap.php"
>
<testsuites>
<testsuite name="StdTestSuite">
<directory>
tests/
</directory>
</testsuite>
</testsuites>
</phpunit>
The problem was the stupidest thing ever.
You can't have whitespace inside the tag.
So what you need to have in you phpunit.xml file is this
...
<testsuite name="StdTestSuite">
<directory>tests/</directory>
</testsuite>
...
Then running
phpunit
Should work

Resources