PHPUnit
Moodle 2.3
What is PHPUnit
PHPUnit by Sebastian Bergmann is an advanced unit testing framework for PHP. It is installed as Composer dependency and is not part of Moodle installation. To run PHPUnit tests, you have to manually install it on your development computer or test server.
Read the excellent guide at
Installation of PHPUnit via Composer
Windows may require additional installation steps. On Windows go to https://getcomposer.org/download/ and download the Composer-Setup.exe file
- Execute Composer installer
cd /your/moodle/dirroot php composer.phar install
(If that gives you connection problems try...)
php composer.phar install --prefer-source
Troubleshooting:
- On Windows if you are behind a proxy you will need to setup an environment variable called HTTP_PROXY with a value detailing your HTTP Proxy address and port before composer will correctly download files.
- You may be prompted for github credentials when installing composer dependencies.
- This is used to generate an personal access token to avoid being rate limited by github.
- If you have Two Factor Authentication enabled on your github account, or do not wish to supply your own credentials you will need to generate a token manually:
- Visit https://github.com/settings/applications and request personal access token
- Copy this token and add it to your ~/.composer/config.json
- ( See composer issue #2280 for further details of this bug.)
Detailed instructions:
Detailed instructions:
Uninstalling previous PEAR based version
Before using composer, this page used to suggest to install phpunit via PEAR. If you did so, you may wish to uninstall that package now. This should work:
$ pear uninstall phpunit/DbUnit $ pear uninstall phpunit/PHPUnit
Initialisation of test environment
Our PHPUnit integration requires a dedicated database and dataroot. First, add a new dataroot directory and prefix into your config.php, you can find examples in config-dist.php (scroll down to 'Section 9').
$CFG->phpunit_prefix = 'phpu_'; $CFG->phpunit_dataroot = '/home/example/phpu_moodledata';
Some PHPUnit tests require a live internet connection. If your system does not have a direct connection to the Internet, you also need to specify your proxy in config.php - even though you normally specify it by using the admin settings user interface. (If you do not use a proxy, you can skip this step.) Check the settings on the relevant admin settings page, or from the mdl_config table in your database, if you are unsure of the correct values.
// Normal proxy settings $CFG->proxyhost = 'wwwcache.example.org'; $CFG->proxyport = 80; $CFG->proxytype = 'HTTP'; $CFG->proxybypass = 'localhost, 127.0.0.1, .example.org'; // Omit the next lines if your proxy doesn't need a username/password: $CFG->proxyuser = 'systemusername'; $CFG->proxypassword = 'systempassword';
From Moodle 2.8.5 onwards, you can also provide specific database settings for unit testing (if these are not provided, the standard database settings will be used):
$CFG->phpunit_dbtype = 'pgsql'; // 'pgsql', 'mariadb', 'mysqli', 'mssql', 'sqlsrv' or 'oci' $CFG->phpunit_dblibrary = 'native'; // 'native' only at the moment $CFG->phpunit_dbhost = '127.0.0.1'; // eg 'localhost' or 'db.isp.com' or IP $CFG->phpunit_dbname = 'mytestdb'; // database name, eg moodle $CFG->phpunit_dbuser = 'postgres'; // your database username $CFG->phpunit_dbpass = 'some_password'; // your database password
Then you need to initialise the test environment using following command.
cd /home/example/moodle php admin/tool/phpunit/cli/init.php
This command has to be repeated after any upgrade, plugin (un)installation or if you have added tests to a plugin you are developing:
NOTE: make sure that your php cli executable (or the one you want to use) is correctly on your path as the individual init scripts will call it repeatedly. Also, ensure en_AU locale is installed on your server.
LDAP
If you want to run LDAP unit tests you must have a working, configured LDAP environment on your test server. There must be a basic LDAP tree structure in place or tests will fail with "Search: No such object". Build an LDAP tree structure in a new shell prompt:
$ ldapadd -H ldap://127.0.0.1 -D "cn=admin,dc=yourcomputer,dc=local" -W dn:dc=yourcomputer,dc=local objectClass:dcObject objectClass:organizationalUnit dc:yourcomputer ou:YOURCOMPUTER
In config.php tell Moodle where to look for your test LDAP environment:
// Constants for auth/ldap tests define('TEST_AUTH_LDAP_HOST_URL', 'ldap://127.0.0.1'); define('TEST_AUTH_LDAP_BIND_DN', 'cn=admin,dc=yourcomputer,dc=local'); define('TEST_AUTH_LDAP_BIND_PW', '*'); define('TEST_AUTH_LDAP_DOMAIN', 'dc=yourcomputer,dc=local'); // Constants for lib/ldap tests define('TEST_LDAPLIB_HOST_URL', 'ldap://127.0.0.1'); define('TEST_LDAPLIB_BIND_DN', 'cn=admin,dc=yourcomputer,dc=local'); define('TEST_LDAPLIB_BIND_PW', '*'); define('TEST_LDAPLIB_DOMAIN', 'dc=yourcomputer,dc=local');
Test execution
To execute all test suites from main configuration file execute the vendor/bin/phpunit
script from your $CFG->dirroot
directory.
cd /home/example/moodle vendor/bin/phpunit
The rest of examples uses phpunit
, please substitute it with vendor/bin/phpunit
or create a shortcut in your dirroot.
In IDEs, you may need to specify the path to the PHPUnit configuration file. Use the absolute path to phpunit.xml
from your $CFG->dirroot
.
There is an alternative script for running of tests via web interface: admin/tool/phpunit/webrunner.php
. Use this as the last resort only when you cannot use the command-line interface on your test server. It will most probably break due to permissions problems if you try to execute it both from command-line and from webrunner. This feature is not officially supported.
How to run only some tests
Running a single test quickly
The fastest way to run a single test is:
vendor/bin/phpunit my_test_class_name my/tests/filename.php
This is faster than other methods because it avoids the need to search for the test file, but you should be careful because it may be possible to run tests this way which are not included in the normal run. If you use this method, do at least one full test run (or --group run, as below) to ensure the test can be found.
Please note the path name is optional if the testcase class and file names are standardised as described in Writing PHPUnit tests.
Using the @group annotation
If you add annotations like
/**
* Unit tests for {@link stack_cas_keyval}.
* @group qtype_stack
*/
class qtype_stack_cas_keyval_exception_testcase extends basic_testcase {
to all the classes in your plugin, then you can run just the tests for your plugin by doing
phpunit --group qtype_stack
Therefore, it is suggested that you annotate all your tests with the Frankenstyle name of your plugin.
Using multiple phpunit.xml files
It's easy to create alternative phpunit.xml files defining which tests must be run together. For reference, take a look to the default /phpunit.xml available in your base directory once the testing environment has been initialised. After creating the custom file you will be able to run those tests with
vendor/bin/phpunit -c path/to/your/alternative/phpunit/file.xml
Also, for commodity, you can use this command:
php admin/tool/phpunit/cli/util.php --buildcomponentconfigs
It will, automatically, create one valid phpunit.xml file within each component (plugin or subsystem) and other important directories, so later you will be able to execute tests like
vendor/bin/phpunit -c mod/forum[/phpunit.xml] // Note that it's not needed to specify the name of the file (if it is 'phpunit.xml'). vendor/bin/phpunit -c question vendor/bin/phpunit -c question/type/calculated vendor/bin/phpunit -c backup vendor/bin/phpunit -c lib/dml ...
or, also
cd directory/with/phpunit.xml phpunit
External test resources
Moodle 2.6
By default Moodle phpunit tests contact http://download.moodle.org server when testing curl related functionality. Optionally you may checkout a local copy of the test scripts and access it instead:
- clone https://github.com/moodlehq/moodle-exttests to web directory
- add to your config.php or modify phpunit.xml file
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost/moodle-exttests');
Writing new tests
Conversion of existing SimpleTests
PHPUnit support in IDEs
Common Unit Test Problems
Performance
A typical run of full PHPUnit tests for Moodle 2.7 takes 10-20 minutes depending on the machine. If tests run slowly for you:
- Ensure you are using a database and filesystem running on the same machine that is running the tests (not on a remote server).
- Apply developer-only performance settings to your database: Postgres Tuning For Developers