Including PHPUnit tests in SonarQube analysis
In my previous article I explained how to set up SonarQube to analyze PHP source code. This article describes how to include the results of PHPUnit tests in this analysis.
I assume you have PHPUnit installed or else you would not be able to run your PHPUnit tests. I prefer to install it globally so the phpunit
command runs from every folder..
The setup described here only includes the necessary configuration files and settings. Adjust them to the needs of you project.
- Folder structure
- PHPUnit configuration file
- Running tests
- Analyzing test results
- Example files
- Links
Folder structure
All tests are stored together with the rest of the project, but in a separate folder.
This is the basic folder structure I use for PHP components, which is inspired by the default structure used by Apache Maven:
my-project ├─ build └─ src ├─ main | └─ php | └─ kwebble | └─ namespace | └─ MyClass.php └─ test └─ php ├─ kwebble | └─ namespace | └─ MyClassTest.php ├─ bootstrap.php └─ phpunit.xml
In this structure:
build
is generated during testing and not stored in version control.src
contains all source codemain
contains all source code used at runtime. This folder is also configured as the PSR-4 autoload folder for Composer.test
contains all source code used for tests, including support classes if necessary.kwebble
is the top namespace for my PHP classes.
Test classes have the same namespaces as the classes they test, but as you can see they are stored in different folders.
The name of a test class is equal to the class it tests plus the Test
suffix.
PHPUnit configuration file
The PHPUnit configuration is stored in my-project/src/test/php/phpunit.xml
, in the PHP test code folder. Here is an example configuration:
<phpunit bootstrap="bootstrap.php" stderr="true" > <testsuites> <testsuite name="My project"> <directory>.</directory> </testsuite> </testsuites> <logging> <log type="coverage-clover" target="../../../build/tests-clover.xml"/> <log type="junit" target="../../../build/tests-junit.xml" logIncompleteSkipped="false"/> </logging> </phpunit>
This configuration defines:
bootstrap.php
, which contains code to set up the PHP environment.- a testsuite that uses the current folder
.
to search for tests. - the generated output in
clover
andjunit
format. Thes files are stored in themy-project/build
folder of the project
The code in bootstrap.php
sets up the PHP environment so that the test can run:
<?php $rootPath = realpath(__DIR__ . '/../../..'); $vendorPath = $rootPath . '/vendor'; $testClassPath = $rootPath . '/src/test/php/kwebble/namespace'; $loader = require $vendorPath . '/autoload.php'; $loader->addPsr4('kwebble\namespace\test\', $testClassPath);
It includes the Composer autoloader so the tested classes can be found and also adds the classes with the tests.
Running tests
Together the configurations in these files should be able to run the tests. From the base folder of the project run PHPUnit with this command:
phpunit -c src/test/php/phpunit.xml
The results of the test run are stored in the my-project/build
folder.
Analyzing test results
The SonarQube configuration to read the test results is set in sonar.properties
:
sonar.tests=src/test/php sonar.php.tests.reportPath=build/tests-junit.xml sonar.php.coverage.reportPath=build/tests-clover.xml sonar.coverage.exclusions=src/test/php/**/*.php
It defines these properties:
sonar.tests
the path to the tested code.sonar.php.tests.reportPath
the path to the file with test results.sonar.php.coverage.reportPath
the path to the file with test coverage data.sonar.coverage.exclusions
the excluded source code, so the tests themselves are excluded from the analysis.
With this configuration run the SonarQube analysis by executing the sonar-runner
command. After completion you can view the unit test related metrics and the Unit Tests Coverage widget of SonarQube:
Example files
On GitHub you can find a small component that uses the same files and configurations described in this article. You can use it as a base for your own projects or just to view a working example.
Links
- PHPUnit
- SonarQube
- Example component on GitHub (directory-folder-path)