Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
minLevel1
maxLevel2
outlinefalse
styledefaultnone
typelist
printabletrue

Overview

Code coverage is a great valuable tool to find identify gaps in your code coverage and making sure test suite and ensure that your code is adequately covered with by tests. High However, high code coverage alone 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 high-quality tests. It is critical to focus on writing well-constructed tests, as this will have a greater impact than striving to cover every line of code.

PHPUnit and code coverage

Traditionally PHPUnit comes with PHPUnit provides built-in 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.

various formats. To generate code coverage, PHPUnit relies on either XDdebug XDebug or pcov. The performance of While pcov is superior to XDebug but we will show how you can run it with more performant than XDebug, this guide demonstrates how to use both.

...

Configuring and

...

generating code coverage reports

...

Initialise PHPUnit

The first step is to initialise the PHPUnit environment.

...

(latest version)

Info

This guide details how to configure and generate a code coverage report for the latest version of Totara. For older implementations, please see the Configurations for older versions section.

Step 1: Initialise PHPUnit

Code Block
php test/phpunit/phpunit.php init

Totara 12

Code Block
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.

...

If you are using the /wiki/spaces/IN/pages/108151852, you can instead run installunit or install_phpunit commands in your PHP container.

Step 2: Configure whitelists

To generate code coverage, you need to define a whitelist in your phpunit.xml file. Without this, you will encounter the following error:

Code Block
Error: Incorrect whitelist config, no code coverage will be generated.

Add the following whitelist configuration to the your phpunit.xml file directly after the closing </php> tag. Adjust the paths to match your project’s structure. Only directories and files included in the whitelist will appear in the coverage report.

Note

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

Code Block
<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>
Code Block
languagexml
</php>
...
<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>
    </whitelist>include>
</filter>source>

Totara 12

File: phpunit.xml

Same as for Totara 13 except that you have to add the processUncoveredFilesFromWhitelist="false" addUncoveredFilesFromWhitelist="false" attributes.

Code Block
<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>

...

Important notes

...

  • Use full paths to avoid incorrect whitelist configuration errors.

  • 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.

  • Limit the whitelist to relevant files and directories to reduce the report generation time.

  • If <source> does not work, replace it with <coverage>.

Step 3: Generate coverage reports

Using XDebug

Ensure XDebug is installed. Use the following commands to generate an HTML-formatted coverage report:

Code Block
XDEBUG_MODE=coverage php test/phpunit/phpunit.php run --filter=totara_core --coverage-html /var/www/totara/src/dev/coverage

Totara 12

Code Block
XDEBUG_MODE=coverage vendor/bin/phpunit --filter=totara_core --coverage-html /var/www/html/coverage_report

...

You can also generate a Clover XML report to be used in other tools:Totara 13 and aboveReport

Code Block
XDEBUG_MODE=coverage php test/phpunit/phpunit.php run --filter=totara_core --coverage-clover /tmp/coverage_report.xml

Totara 12

Code Block
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.

Using pcov

pcov is an a high-performance alternative to XDebug. It is much more performant. To get set it runningup:

  1. Install pcov and note the pcov extension with

    Code Block
    pecl install pcov
    When running this command, it will output the path it saved itself in. This will be something like

    generated path to pcov.so, e.g. /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

    Enable and configure the extension in the php.ini

    The “path/to/pcov.so” will be the one you noted down from step 1.

    Code Block
    Code Block
    composer require pcov/clobber
    vendor/bin/pcov clobber
  2. Ensure PHP has enough memory in php.ini. Give it heaps, as code coverage is memory intensive.

    Code Block
    memory_limit=8G
  3. pecl install pcov

  4. Update php.ini. Note here also that we update the memory_limit to 8G:

    Code Block
    languageini
    memory_limit=8G
    
    [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
  5. 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.

Code Block
phpunit --coverage-html /var/www/html/coverage_report /path/to/plugin/to/test

or

...

To find your php.ini’s location, run the following command and see the path in the output:

Code Block
php --ini
  1. Generate the report:

    Code Block
    phpunit --coverage-html /var/www/html/coverage_report

...

Totara 12

...

  1.  /path/to/

...

  1. plugin/to/test

Viewing the reportusing Totara docker developer environment

If using our Totara Docker Development environment - /wiki/spaces/IN/pages/108151852 - you can replace the output path for the coverage report /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:

  1. On your PHP container: 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:

Code Block
languagebash
chmod o+rx -R /var/www/totara/src/SITENAME/coverage_report

...

You will need to run the above each time you generate a new coverage report.

  1. On your local machine: add your new “coverage_report site” in the hosts record on your local machine (not in the PHP container)file, so that we can access it via the browser. Replace XX with the PHP version you are currently using. For example if you’re using PHP 8.3, this will be 83. Once this step has been run, you should not need to repeat this step.

Code Block
languagebash
sudo -- sh -c "echo \"127.0.0.1 coverage_report.totaraXX\" >>> /etc/hosts "
  1. 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.

Configurations for older versions

Totara 13

Initialisation:

Code Block
php test/phpunit/phpunit.

...

php init

Whitelist configuration:

Note

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.

Code Block
languagexml
<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>
Info

Make sure you use full paths to the files and directories. Otherwise PHPUnit might show an error about an incorrect whitelist configuration.

Generating coverage reports:

Code Block
XDEBUG_MODE=coverage php test/phpunit/phpunit.php run --filter=totara_core --coverage-html /var/www/totara/src/dev/coverage

Totara 12

Initialisation:

Code Block
php admin/tool/phpunit/cli/init.php

Whitelist configuration:

Note

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.

Code Block
languagexml
<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>
Info

Make sure you use full paths to the files and directories. Otherwise PHPUnit might show an error about an incorrect whitelist configuration.

Generating coverage reports:

Code Block
XDEBUG_MODE=coverage vendor/bin/phpunit --filter=totara_core --coverage-html /var/www/html/coverage_report

pcov installation:

Install pcov/clobber which adds pcov support to PHPUnit 7:

Code Block
composer require pcov/clobber
vendor/bin/pcov clobber

...

Integration with PHPStorm

PHPStorm has the ability to run code coverage anaylsis analysis in product using XDebug or pcov. The analysis is automatically loaded into the platform and displayed both in the Coverage coverage tool, and in-editor when looking at files. Their documentation on code coverage explains how to set it up.

A Here are 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

...

  1. Incorrect phpunit.xml

...

  1. paths: Ensure paths point to the correct Totara installation.

  2. Whitelist misconfiguration: Use pwd to verify paths and ensure full paths in your configuration.

Further reading