Unit testing in Totara 13

About our unit tests

Totara 13 makes use of PHPUnit 8.5 for unit testing. The installation of necessary libraries is managed via Composer. The test environment is automatically reset after each test, including database state and dataroot files.

It is important to note that since 2016 it is a requirement of every change being made to code that it accompanied by tests. Unit tests for back-end changes, and acceptance tests for front-end changes.

Testing instructions for older Totara versions can be found at Unit testing.

Getting it running

1. Create test/phpunit/config.php

Before initialising PHPUnit you need to tell Totara how to connect to the test database and where to store test files.

You can start by copying sample configuration file, then edit the new test/phpunit/config.php file to specify database connection and dataroot location.

cd test/phpunit
cp config.example.php config.php
vi config.php

2. Initialise your site for testing

We need to initialise PHPUnit within Totara so that it is ready to run.

cd test/phpunit
php phpunit.php init

This will download Composer, install libraries in vendor directory, install the database structures and prepare dataroot directory.

You are now ready to run tests.

Run tests

This can be done in a number of ways, including but not limited to the following:

Running all tests

cd test/phpunit
./vendor/bin/phpunit

Running a test suite

./vendor/bin/phpunit --testsuite="mod_facetoface_testsuite"

Running a single testcase

Like above except that you provide test file as an argument.

./vendor/bin/phpunit ../../server/user/tests/userdata_username_test.php

Running a single test

It's also possible to run a single test within a test case using the filter argument.

./vendor/bin/phpunit --filter=test_export ../../server/user/tests/userdata_username_test.php

Note that when using the filter argument you don't actually need to specify a specific file - doing so just limits the scope of PHPUnit.

Running a group of tests

More recently we have been writing tests and defining them as groups, so that you can run related tests that are spread across the entire system with ease.

./vendor/bin/phpunit --group totara_userdata

In general it is not necessary to use groups because the naming of test case files and classes makes filtering a more reliable option.

Running tests in parallel

Paratest is a tool which enables you to run the tests in parallel reducing the overall runtime of the test suite from several hours to one hour.

The good news is that we have a CI system that can run tests for you in parallel mode, and at your request against different versions of PHP and different databases.

Initiate the tests

To initiate your site for a parallel test run:

php phpunit.php parallel_init --processes=4

The processes parameter cannot be omitted.

Running the tests

We provide a script to trigger the run. Just supply the same 'processes' argument as during the init.

php phpunit.php parallel_run --processes=4

Other test options

Performance testing unit tests

To better understand the tests you are writing, and to help us understand the performance costs of our test cases, we have a means within Totara with which we can test the performance of our unit tests.

To start add the following to your test/phpunit/config.php:

define('PHPUNIT_PROFILING', true);

Now run tests.

You will find the following two files have appears within your source directory:

  • phpunit_profile_classes_postgres.csv

  • phpunit_profile_methods_postgres.csv

These two files contain the timings on every class and method when you last ran PHPUnit.

Distribution tests

There is a special type of test that is intended for distribution purposes only. You can run them by adding the following to the test/phpunit/config.php file. These tests are run automatically on our CI, they may fail when any third-party add-ons are present.

define('TOTARA_DISTRIBUTION_TEST', true);

Adding new tests

Naming of test case classes and files

The test case class name must start with a component prefix (aka Frankenstyle) and must end with _testcase suffix. Namespaces are not allowed.

Test case file name is derived from the class name, it omits the component prefix and uses _test.php suffix.

For example server/totara/cohort/tests/enrol_test.php file contains class: 

class totara_cohort_enrol_testcase extends advanced_testcase {
    public function test_role_updates() {
        // test goes here
    }
}

More information is available at https://phpunit.readthedocs.io/en/8.5/.