Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

PHPUnit: Difference between revisions

From MoodleDocs
m (Protected "PHPUnit": Developer Docs Migration ([Edit=Allow only administrators] (indefinite)))
 
(114 intermediate revisions by 26 users not shown)
Line 1: Line 1:
{{Work in progress}}
{{Template:Migrated|newDocId=/general/development/tools/phpunit}}
{{Infobox Project
|name = PHPUnit
|state = Work in progress
|tracker = MDL-32323, MDL-32149, MDL-31857
|discussion = [http://moodle.org/mod/forum/discuss.php?d=198470]
|assignee = [[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]]
}}
{{Moodle 2.3}}
{{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.


PHPUnit by Sebastian Bergmann is the most advanced unit testing framework for PHP.
Read the excellent guide at
* [https://phpunit.de/documentation.html PHPUnit Manual]
=Installation of PHPUnit via Composer=
* Install Composer
Instructions for installing composer on all platforms are here: https://getcomposer.org/download/


=Installing PHP=
Install the composer.phar file to your moodle folder.
* Execute Composer installer
cd /your/moodle/dirroot


You need to install PHP on your own computer. If you already have it installed you can skip this stage.
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 [https://gist.github.com/andrewnicols/c5377ed25a9df1006ce1 ~/.composer/config.json]
** ( See [https://github.com/composer/composer/issues/2280 composer issue #2280] for further details of this bug.)


== Real operating systems ==


(No instructions, you need to figure this out yourself then add it in here.)
Detailed instructions:
 
* [http://getcomposer.org/doc/00-intro.md Composer documentation]
== Windows 7 ==
Detailed instructions:
 
* [[PHPUnit installation in Windows]]
Do not try to install PHP 5.4 as there is no installer and it doesn't include the PEAR installation batch file. Instead, you have to use PHP 5.3.
* [[PHPUnit installation in OS X]]
 
== Uninstalling previous PEAR based version ==
* http://windows.php.net/download/#php-5.3
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
You probably want the thread-safe version.
  $ pear uninstall phpunit/PHPUnit
 
= PHPUnit versions =
While going through the installation, you probably should use all default options, except:
The following table shows what PHPUnit version is installed in which Moodle version when using the default composer setup.
 
{| class="wikitable" border="1"
# There is a question about which web server to use. Since you do not have PHP installed on your system already, you probably don't want to run a web server, so choose 'Do not setup a web server'.
|-
# There is a list of features. Expand 'Extras' and turn on 'PEAR install'.
! Moodle version
 
! PHPUnit version
After install completes, open a new terminal and run 'php -version' to verify that it is installed.
!Links
 
|-
=Installation of PHPUnit support=
| Moodle 3.11 - 4.0
 
| PHPUnit 9.5
PHPUnit is distributed as PEAR package, it is not part of Moodle installation. You have to manually install it on your dev computer. The installation procedure depends on your operating system or the way you installed PHP.
|[https://phpunit.readthedocs.io/en/9.5/ Documentation]
 
|-
== Real operating systems ==
| Moodle 3.10
 
| PHPUnit 8.5
Installation steps:
|[https://phpunit.readthedocs.io/en/8.5/ Documentation]
# install or enable PEAR support in your PHP, see [http://pear.php.net/manual/en/installation.getting.php official PEAR installation guide]
|-
# upgrade PEAR, in *nix usually  <code>sudo pear upgrade PEAR</code>
| Moodle 3.7 - 3.9
# install PHPUnit package as root or Windows administrator (minimum required version is 3.6.0):
| PHPUnit 7.5
pear config-set auto_discover 1
|[https://phpunit.readthedocs.io/en/7.5/ Documentation]
pear install pear.phpunit.de/PHPUnit
|-
pear install phpunit/DbUnit
| Moodle 3.4 - 3.6
 
| PHPUnit 6.5
== Windows 7 ==
|[https://phpunit.de/manual/6.5/en/ Documentation]
 
|-
* Click Start button. Type 'cmd' and, instead of pressing Return, press Ctrl + Shift + Return. This should give you a popup prompt to confirm permissions, then run the command prompt as administrator.
| Moodle 3.2 - 3.3
 
| PHPUnit 5.5
cd "\Program Files (x86)"\php
|[https://phpunit.de/manual/5.5/en/ Documentation]
go-pear
|-
 
| Moodle 3.1
* Hit Return repeatedly to accept all defaults.
| PHPUnit 4.8.27
 
|[https://phpunit.de/manual/4.8/en/ Documention 4.8]
start PEAR_ENV.reg
|}
 
* Accept adding junk to your registry.
 
* Note that when I tried this, each time you run 'pear' it will come with a messagebox popup error, but this does not seem to stop it working.
 
* If you use an HTTP proxy:
 
pear config-set http_proxy my.proxy.is:80
 
* Install PHPUnit and DbUnit:
 
pear config-set auto_discover 1
pear upgrade-all
pear install pear.phpunit.de/PHPUnit
pear install pear.phpunit.de/DbUnit
 
* Using a text editor, edit the 'phpunit' shell script in c:\Program Files (x86)\PHP. Change the first line to:
 
#!php.exe


=Initialisation of test environment=
=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').
Our PHPUnit integration requires a dedicated database and dataroot. First add new dataroot directory and prefix into your config.php, you can find examples in config-dist.php
 
  $CFG->phpunit_prefix = 'phpu_';
  $CFG->phpunit_prefix = 'phpu_';
  $CFG->phpunit_dataroot = '/home/example/phpu_moodledata';
  $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.
Then you need to initialise the test environment using following command:
// 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):
<pre>$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</pre>
Then you need to initialise the test environment using following command.
  cd /home/example/moodle
  cd /home/example/moodle
  php admin/tool/phpunit/cli/init.php
  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:
<pre>
$ 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
</pre>
In config.php tell Moodle where to look for your test LDAP environment:
<pre>
// 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');


This command has to be used also after any upgrade, plugin (un)installation or adding tests to new plugin.
// Constants for enrol/ldap tests.
define('TEST_ENROL_LDAP_HOST_URL', 'ldap://127.0.0.1');
define('TEST_ENROL_LDAP_BIND_DN', 'cn=admin,dc=yourcomputer,dc=local');
define('TEST_ENROL_LDAP_BIND_PW', '*');
define('TEST_ENROL_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');
</pre>
=Test execution=
=Test execution=
 
To execute all test suites from main configuration file execute the <syntaxhighlight lang="php">vendor/bin/phpunit</syntaxhighlight> script from your <syntaxhighlight lang="php">$CFG->dirroot</syntaxhighlight> directory.
To execute all test suites from main configuration file execute <code>phpunit</code> script from your <code>$CFG->dirroot</code> directory:
 
  cd /home/example/moodle
  cd /home/example/moodle
  phpunit
  vendor/bin/phpunit
The rest of examples uses <syntaxhighlight lang="php">phpunit</syntaxhighlight>, please substitute it with <syntaxhighlight lang="php">vendor/bin/phpunit</syntaxhighlight> 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 <syntaxhighlight lang="php">phpunit.xml</syntaxhighlight> from your <syntaxhighlight lang="php">$CFG->dirroot</syntaxhighlight>.


Use relative path to the test file for execution of one test only (test case classname followed by path to test file):


cd /home/example/moodle
There is an alternative script for running of tests via web interface: <syntaxhighlight lang="php">admin/tool/phpunit/webrunner.php</syntaxhighlight>. 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.
phpunit core_phpunit_basic_testcase lib/tests/phpunit_test.php


In IDEs you may need to specify path to configuration file, use absolute path to <code>phpunit.xml</code> from your <code>$CFG->dirroot</code>.


= Running tests via web =
===How to run only some tests===
 
==== Running a single test quickly (PHPUnit 9) ====
Although the recommended method is the command line, for cases when you want to run tests on a remote server and do not have command-line access, you can also run tests via the web:
{{Moodle 3.11}}
 
The fastest way to run a single test in PHPUnit 9.5 and higher (Moodle 3.11 and higher) is to use the filter argument:
admin/tool/phpunit/webrunner.php
<syntaxhighlight lang="bash">
 
vendor/bin/phpunit --filter tool_dataprivacy_metadata_registry_testcase
This is a 'secret' feature and may not be well supported.
</syntaxhighlight>
To run all tests provided by the single component, use suite and the name it has in the phpunit.xml file. Example:
<syntaxhighlight lang="bash">
vendor/bin/phpunit --testsuite workshopform_accumulative_testsuite
</syntaxhighlight>
Alternatively if you have config files built for each component:
<syntaxhighlight lang="bash">
vendor/bin/phpunit -c mod/workshop/form/accumulative/
</syntaxhighlight>
==== Running a single test quickly (PHPUnit 8) ====
{{Moodle 3.10}}
The fastest way to run a single test in PHPUnit 8.5 and lower (Moodle 3.10 and lower):
<syntaxhighlight lang="bash">
vendor/bin/phpunit my/tests/filename.php
</syntaxhighlight>
so, run this command in the CLI to see a real test in action:
<syntaxhighlight lang="bash">
vendor/bin/phpunit cohort/tests/cohortlib_test.php
</syntaxhighlight>
You can also run a single test method inside a class:
<syntaxhighlight lang="bash">
vendor/bin/phpunit --filter test_function_name path/to/file.php
</syntaxhighlight>
Note: You should be careful because it may be possible to run tests this way which are not included in the normal run if, for example, the file is not placed in the correct location. If you use this method, do at least one full test run (or --group run, as below) to ensure the test can be found.


Filters can also be applied to capture a group of similar tests across all testsuites:
<syntaxhighlight lang="bash">
vendor/bin/phpunit --filter test_flag_user
</syntaxhighlight>
It is also possible to run all tests in a component (subsystem or plugin) by using the testsuite option:
<syntaxhighlight lang="bash">
vendor/bin/phpunit --testsuite mod_forum_testsuite
vendor/bin/phpunit --testsuite core_privacy_testsuite
vendor/bin/phpunit --testsuite core_privacy_testsuite --filter test_component_is_compliant
</syntaxhighlight>
==== Using the @group annotation ====
If you add annotations like
<syntaxhighlight lang="php">
namespace qtype_stack;
/**
* Unit tests for {@link stack_cas_keyval} @ qtype/stack/tests/cas_keyval_test.php.
* @group qtype_stack
*/
class cas_keyval_test extends \basic_testcase {
</syntaxhighlight>
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 <syntaxhighlight lang="php">define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost/moodle-exttests');</syntaxhighlight>
=Writing new tests=
* read [http://www.phpunit.de/manual/current/en/ official PHPUnit online documentation]
* see [[Writing PHPUnit tests]]
=Conversion of existing SimpleTests=
* see [[SimpleTest conversion]]
=PHPUnit support in IDEs=
=PHPUnit support in IDEs=
* [http://www.phpsrc.org/projects/pti-phpunit/wiki/ Eclipse PHP Tool Integration]
* [[Setting up Eclipse]]
* [http://blog.jetbrains.com/webide/2009/12/phpunit-support/ PHPStorm IDE]
* [[Setting up Netbeans]]
* [http://netbeans.org/kb/docs/php/phpunit.html Netbeans]
* [[Setting up PhpStorm]]
=Common Unit Test Problems=
[[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]]
=Command line tips=
* Run all tests for a plugin (mod_mymodule in this example): vendor/bin/phpunit --testsuite=mod_mymodule_testsuite
* Run only named test: vendor/bin/phpunit --filter=test_my_test_function_name
* Display each test name before running it (useful e.g. if it crashes before the end and you want to know which test it was running at that point) vendor/bin/phpunit --debug (you will probably want to redirect this to a file as it gets very long).
[[Category:Unit testing]]


=See also=
[[ja:PHPUnit]]
* [http://www.phpunit.de/manual/current/en/ PHPUnit online documenatation]

Latest revision as of 05:33, 29 June 2022

Important:

This content of this page has been updated and migrated to the new Moodle Developer Resources. The information contained on the page should no longer be seen up-to-date.

Why not view this page on the new site and help us to migrate more content to the new site!

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

  • Install Composer

Instructions for installing composer on all platforms are here: https://getcomposer.org/download/

Install the composer.phar file to your moodle folder.

  • 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:
    • ( 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

PHPUnit versions

The following table shows what PHPUnit version is installed in which Moodle version when using the default composer setup.

Moodle version PHPUnit version Links
Moodle 3.11 - 4.0 PHPUnit 9.5 Documentation
Moodle 3.10 PHPUnit 8.5 Documentation
Moodle 3.7 - 3.9 PHPUnit 7.5 Documentation
Moodle 3.4 - 3.6 PHPUnit 6.5 Documentation
Moodle 3.2 - 3.3 PHPUnit 5.5 Documentation
Moodle 3.1 PHPUnit 4.8.27 Documention 4.8

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 enrol/ldap tests.
define('TEST_ENROL_LDAP_HOST_URL', 'ldap://127.0.0.1');
define('TEST_ENROL_LDAP_BIND_DN', 'cn=admin,dc=yourcomputer,dc=local');
define('TEST_ENROL_LDAP_BIND_PW', '*');
define('TEST_ENROL_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 (PHPUnit 9)

Moodle 3.11

The fastest way to run a single test in PHPUnit 9.5 and higher (Moodle 3.11 and higher) is to use the filter argument:

vendor/bin/phpunit --filter tool_dataprivacy_metadata_registry_testcase

To run all tests provided by the single component, use suite and the name it has in the phpunit.xml file. Example:

vendor/bin/phpunit --testsuite workshopform_accumulative_testsuite

Alternatively if you have config files built for each component:

vendor/bin/phpunit -c mod/workshop/form/accumulative/

Running a single test quickly (PHPUnit 8)

Moodle 3.10

The fastest way to run a single test in PHPUnit 8.5 and lower (Moodle 3.10 and lower):

vendor/bin/phpunit my/tests/filename.php

so, run this command in the CLI to see a real test in action:

vendor/bin/phpunit cohort/tests/cohortlib_test.php

You can also run a single test method inside a class:

vendor/bin/phpunit --filter test_function_name path/to/file.php

Note: You should be careful because it may be possible to run tests this way which are not included in the normal run if, for example, the file is not placed in the correct location. If you use this method, do at least one full test run (or --group run, as below) to ensure the test can be found.

Filters can also be applied to capture a group of similar tests across all testsuites:

vendor/bin/phpunit --filter test_flag_user

It is also possible to run all tests in a component (subsystem or plugin) by using the testsuite option:

vendor/bin/phpunit --testsuite mod_forum_testsuite
vendor/bin/phpunit --testsuite core_privacy_testsuite
vendor/bin/phpunit --testsuite core_privacy_testsuite --filter test_component_is_compliant

Using the @group annotation

If you add annotations like

namespace qtype_stack;
/**
 * Unit tests for {@link stack_cas_keyval} @ qtype/stack/tests/cas_keyval_test.php.
 * @group qtype_stack
 */
class cas_keyval_test 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:

  1. clone https://github.com/moodlehq/moodle-exttests to web directory
  2. 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

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

Command line tips

  • Run all tests for a plugin (mod_mymodule in this example): vendor/bin/phpunit --testsuite=mod_mymodule_testsuite
  • Run only named test: vendor/bin/phpunit --filter=test_my_test_function_name
  • Display each test name before running it (useful e.g. if it crashes before the end and you want to know which test it was running at that point) vendor/bin/phpunit --debug (you will probably want to redirect this to a file as it gets very long).