Code coverage is a great tool to find gaps in your code coverage and making sure your code is covered with tests. High code coverage does not guarantee great test quality so please make sure the tests are well written. At the end this will likely be more important than to cover every line of code.
PHPUnit and code coverage
Traditionally PHPUnit comes with support for generating code coverage reports in different formats.
Over time PHPUnit changed how it is being configured and run. As different Totara versions also come with different PHPUnit versions this document outlines the approach to set up your environment and generate coverage for multiple versions.
To generate code coverage PHPUnit relies on either XDdebug or pcov. The performance of pcov is superior to XDebug but we will show how you can run it with both.
How to configure and generate code coverage reports
Initialise PHPUnit
The first step is to initialise the PHPUnit environment.
Totara 13 and above
php test/phpunit/phpunit.php init
Totara 12
php admin/tool/phpunit/cli/init.php
Whitelists
In order to generate code coverage you need to provide a whitelist in the phpunit.xml file otherwise you get an error when trying to generate the report.
Error: Incorrect whitelist config, no code coverage will be generated.
Add the following to the phpunit.xml file directly after the </php>
tag.
These are just examples. Please change the whitelist so it matches your needs. Only directories and files included in the whitelist will appear in the report.
Totara 14 and higher
File: test/phpunit/phpunit.xml
<source> <include> <directory suffix=".php">/var/www/totara/src/SITENAME/server/totara/core/classes/local</directory> <directory suffix=".php">/var/www/totara/src/SITENAME/server/totara/core/classes/task</directory> <file>/var/www/totara/src/SITENAME/server/totara/core/classes/visibility_adviser.php</file> </include> </source>
Totara 13
File: test/phpunit/phpunit.xml
<filter> <whitelist> <directory suffix=".php">/var/www/totara/src/SITENAME/server/totara/core/classes/local</directory> <directory suffix=".php">/var/www/totara/src/SITENAME/server/totara/core/classes/task</directory> <file>/var/www/totara/src/SITENAME/server/totara/core/classes/visibility_adviser.php</file> </whitelist> </filter>
Totara 12
File: phpunit.xml
Same as for Totara 13 except that you have to add the processUncoveredFilesFromWhitelist="false" addUncoveredFilesFromWhitelist="false"
attributes.
<filter> <whitelist processUncoveredFilesFromWhitelist="false" addUncoveredFilesFromWhitelist="false"> <directory suffix=".php">/var/www/totara/src/SITENAME/totara/core/classes/local</directory> <directory suffix=".php">/var/www/totara/src/SITENAME/totara/core/classes/task</directory> <file>/var/www/totara/src/SITENAME/totara/core/classes/visibility_adviser.php</file> </whitelist> </filter>
Please make sure you use full paths to the files and directories. Otherwise PHPUnit might show an error about an incorrect whitelist configuration.
You can also use <exclude>
tags. Please refer to the PHPUnit documentation for the full configuration details.
The more files are included in the whitelist the longer it takes to generate the coverage report. It is advised to limit it to the files / directories you are interested in.
Generating coverage
XDebug
Please make sure you have xdebug installed.
To generate the coverage report use the following command to generate a HTML formatted report.
Totara 13 and above
XDEBUG_MODE=coverage php test/phpunit/phpunit.php run --filter=totara_core --coverage-html /var/www/totara/src/dev/coverage
Totara 12
XDEBUG_MODE=coverage vendor/bin/phpunit --filter=totara_core --coverage-html /var/www/html/coverage_report
Please note that this only runs the test for a particular area of the code to reduce the runtime. This should match what you have configured as a whitelist.
You can also generate a Clover XML report to be used in other tools:
Totara 13 and above
XDEBUG_MODE=coverage php test/phpunit/phpunit.php run --filter=totara_core --coverage-clover /tmp/coverage_report.xml
Totara 12
XDEBUG_MODE=coverage vendor/bin/phpunit --filter=totara_core --coverage-clover /tmp/coverage_report.xml
Please refer to the PHPUnit documentation for the available formats.
pcov
pcov is an alternative to XDebug. It is much more performant.
To get it running:
Install the pcov extension with
pecl install pcov
When running this command, it will output the path it saved itself in. This will be something like
/usr/local/lib/php/extensions/no-debug-non-zts-20230831/pcov.so
Only for Totara 12: Install pcov/clobber which adds pcov support to PHPUnit 7
composer require pcov/clobber vendor/bin/pcov clobber
Ensure PHP has enough memory in php.ini. Give it heaps, as code coverage is memory intensive.
memory_limit=8G
Enable and configure the extension in the php.ini
The “path/to/pcov.so” will be the one you noted down from step 1.
[pcov] extension="path/to/pcov.so" pcov.enabled=1 pcov.exclude='~(vendor|tests|node_modules|.git|client|.scannerwork)~' pcov.initial.memory=1073741824 pcov.initial.files=30000
Generate the code coverage
Totara 13 and above
Replace server/path/to/plugin/to/test
with the directory path for the plugin you want to test. For example, if I were generating a code coverage report for Totara hierarchy, this would be server/totara/hierarchy
.
phpunit --coverage-html /var/www/html/coverage_report /path/to/plugin/to/test
or
cd /path/to/code XDEBUG_MODE=off php -dpconv.directory=`pwd` test/phpunit/phpunit.php run --filter=totara_core --coverage-html /var/www/html/coverage_report
Totara 12
cd /path/to/code XDEBUG_MODE=off php -d pcov.directory=`pwd` vendor/bin/phpunit --filter=totara_core --coverage-html /var/www/html/coverage_report
This will create a nicely formatted report for you to inspect, located at /var/www/html/coverage_report
.
If using our Totara Docker Development environment - /wiki/spaces/IN/pages/108151852 - you can replace /var/www/html/coverage_report
with /var/www/totara/src/coverage_report
. Once you’ve done this, execute the following steps to make it accessible:
Once the coverage_report has been created, set the permissions to allow nginx to access the generated files by running the following in your PHP container:
chmod o+rx -R /var/www/totara/src/coverage_report
Add your new “coverage_report site” in the hosts record on your local machine (not in the PHP container). Replace XX with the PHP version you are currently using. For example if you’re using PHP 8.3, this will be 83.
echo "127.0.0.1 coverage_report.totaraXX" > /etc/hosts
Now you should be able to access your coverage report via the web browser by navigating to
http://coverage_report.totaraXX
, where XX is the PHP version you used in step 2.
PHPStorm and XDebug/pcov
PHPStorm has the ability to run code coverage anaylsis in product using XDebug or pcov. The analysis is automatically loaded into the platform and displayed both in the Coverage tool, and in-editor when looking at files. Their documentation on code coverage explains how to set it up.
A few pointers and tips to help however:
You still need to define a whitelist
As a product we support several different versions of PHP - if you're using php-fpm and have them installed you can configure PHPStorm so that you can choose which version you run tests and coverage on
When looking at a testcase file you can click on the little arrows next to test case classes and test case methods and choose to run specific tests
Common Pitfalls
phpunit.xml
path has not been configured correctly
Ensure the paths you provided in phpunit.xml configuration point to where Totara is installed. You can do this by navigating to where you want to run the code coverage report, and then run the command pwd
to print out your current working directory.
Further reading
External: XDebug code coverage analysis
External: PHPDBG documentation
External: pcov repository and documentation