「PHPUnitテストを書く」の版間の差分

提供:MoodleDocs
移動先:案内検索
編集の要約なし
編集の要約なし
195行目: 195行目:
$this->getDataGenerator()->create_repository_type($type, $record, $options);
$this->getDataGenerator()->create_repository_type($type, $record, $options);
</syntaxhighlight>
</syntaxhighlight>
==評定を作成する Creating grades==
==評定を作成する==
===評定カテゴリ Grade categories===
===評定カテゴリ===
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid));
$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid));
$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid, 'fullname' => $fullname));
$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid, 'fullname' => $fullname));
</syntaxhighlight>
</syntaxhighlight>
===評定アイテム Grade items===
===評定アイテム===
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$this->getDataGenerator()->create_grade_item();
$this->getDataGenerator()->create_grade_item();
$this->getDataGenerator()->create_grade_item(array('itemtype' => $itemtype, 'itemname' => $itemname, 'outcomeid' => $outcomeid, 'scaleid' => $scaleid, 'gradetype' => $gradetype));
$this->getDataGenerator()->create_grade_item(array('itemtype' => $itemtype, 'itemname' => $itemname, 'outcomeid' => $outcomeid, 'scaleid' => $scaleid, 'gradetype' => $gradetype));
</syntaxhighlight>
</syntaxhighlight>
===アウトカム Outcomes===
===アウトカム===
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$this->getDataGenerator()->create_grade_outcome();
$this->getDataGenerator()->create_grade_outcome();
213行目: 213行目:
==他のタイプのプラグイン Other types of plugin==
==他のタイプのプラグイン Other types of plugin==
{{Moodle 2.5}}
{{Moodle 2.5}}
Any other type of plugin can have a generator. The generator class should extend component_generator_base, and then you can get an instance using $mygenerator = $this->getDataGenerator()->get_plugin_generator($frankenstylecomponentname);
他のどのようなタイプのプラグインもジェネレータを持つことができます。ジェネレータクラスではcomponent_generator_baseを継承する必要があります。そして、あなたは $mygenerator = $this->getDataGenerator()->get_plugin_generator($frankenstylecomponentname)でインスタンスを取得できます。
他のどのようなタイプのプラグインもジェネレータを持つことができます。ジェネレータクラスではcomponent_generator_baseを継承する必要があります。そして、あなたは $mygenerator = $this->getDataGenerator()->get_plugin_generator($frankenstylecomponentname)でインスタンスを取得できます。


For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.
For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.
=Long tests=
=長いテスト Long tests=
All standard test should execute as fast as possible. Tests that take a loner time to execute (>10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.
All standard test should execute as fast as possible. Tests that take a loner time to execute (>10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.
=Large test data=
=長いテストデータ Large test data=
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]
See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See [[PHPUnit_integration#Extra_methods]]
=Testing sending of messages=
=Testing sending of messages=

2022年5月10日 (火) 15:06時点における版

テンプレート:Moodle 2.3

作成中です - Mitsuhiro Yoshida (トーク)

各テストの開始時に自動的にリセットされて新しくインストールされた状態となります。

ネームスペース

  • /testsディレクトリ以下のすべてのものは名前空間を使用する場合にいくつかの簡単なルールに従う必要があります。これらはテストケース、フィクスチャ、ジェネレータ、そして、一般的にはこれらのディレクトリ内すべてのクラスに適用されます。ご覧ください! (要約 = **/classes ディレクトリに適用されるルールと100% 同じです)。

テストケースクラス

すべてのMoodle単体テストで使用される3つの基本テストクラスがあります - basic_testcase、advanced_testcaseおよびprovider_testcaseです。各クラスファイルには1つのテストケースのみを置くことを強く推奨します。

basic_testcase
データベースおよびdataroot、そしてPHPのグローバルを変更しない非常にシンプルなテストです。例えば公式のPHPUnitチュートリアルにある例を試すときに使用します。
advanced_testcase
Moodleのコードを簡単にテストできるよう強化されたテストケースクラスです。
provider_testcase
プライバシープロバイダのテストを容易にするために拡張された拡張テストケースクラスです。4番目のテストケースクラスはMoodleデータベースレイヤのテスト用に特別に設計されているため、他の目的では使用しないでください。

アサーション Assertions

アサーションに関する完全なリストは以下で閲覧可能です。

Moodle version PHPUnit version Links
Moodle 3.11 PHPUnit 9.5 ドキュメンテーション
Moodle 3.10 PHPUnit 8.5 ドキュメンテーション
Moodle 3.7 - 3.9 PHPUnit 7.5 ドキュメンテーション
Moodle 3.4 - 3.6 PHPUnit 6.5 ドキュメンテーション

サンプルプラグインテストケース Sample plugin testcase

PHPUnit テストはプラグインの tests/*_test.phpファイル (例: mod/myplugin/tests/sample_test.php) に配置されます。このファイルにはadvanced_testcaseを継承したクラスを1つだけ含める必要があります。

 namespace mod_myplugin;

 class sample_test extends \advanced_testcase {
     public function test_adding() {
         $this->assertEquals(2, 1+2);
     }
 }

詳細はPHPUnitインテグレーション#クラスおよびファイル命名規則をご覧ください。

Moodleライブラリファイルのインクルード

あなたがいくつかのMoodleライブラリファイルをインクルードしたい場合、常に「global $CFG」を宣言する必要があります。これはテストケースファイルは自動的にグローバル$CFGを利用できない非Moodleコードからインクルードされる可能性があることが理由です。

自動状態リセット

デフォルトでは各テスト後にMoodleデータベースおよびdatarootは自動的にインストール直後の状態にリセットされます。データベースまたは標準グローバル変数の変更が予想される場合、$this->resetAfterTest()を使用してください

あなたが「Warning: unexpected database modification, resetting DB state」というエラーに遭遇した場合、テストが$this->resetAfterTest()を使用していないためだとお考え下さい。

 namespace mod_myplugin;

 class test_something extends \advanced_testcase {
     public function test_deleting() {
         global $DB;
         $this->resetAfterTest(true);
         $DB->delete_records('user');
         $this->assertEmpty($DB->get_records('user'));
     }
     public function test_user_table_was_reset() {
         global $DB;
         $this->assertEquals(2, $DB->count_records('user', array()));
     }
 }

ジェネレータ

デフォルトのインストールを修正する必要があるテストは新しいコースやユーザ等の作成にジェネレータを使用できます。このページのすべての例はadvanced_testcaseから派生したテストクラスのテストメソッドから使用する必要があります。

単体テストのパラメータにPHPUnit @dataProvider関数を使用している場合、あなたはデータプロバイダ関数でデータジェネレータの使用またはユーザ等を変更できないことに留意してください。データプロバイダでは「データのインスタンス化/生成」をしないでください'。ただ、定義のみしてください。そして、テスト本体ではインスタンス化/生成を進めれます。

ユーザを作成する Creating users

それぞれのテスト開始時にはゲストおよび管理者rの2種類のユーザのみ存在します。あなたがさらにテストアカウントを追加する必要がある場合、以下を使用してください:

 $user = $this->getDataGenerator()->create_user();

You may also specify properties of the user account, for example:

 $user1 = $this->getDataGenerator()->create_user(array('email'=>'user1@example.com', 'username'=>'user1'));

デフォルトではユーザはログインしていないため、 現在の$USER値を変更するにはsetUser()メソッドを使用してください:

 $this->setUser($user1);

Guest and admin accounts have a shortcut methods:

 $this->setGuestUser();
 $this->setAdminUser();

Null can be used to set current user back to not-logged-in:

 $this->setUser(null);

Creating course categories

 $category1 = $this->getDataGenerator()->create_category();
 $category2 = $this->getDataGenerator()->create_category(array('name'=>'Some subcategory', 'parent'=>$category1->id));

Creating courses

 $course1 = $this->getDataGenerator()->create_course();
 
 $category = $this->getDataGenerator()->create_category();
 $course2 = $this->getDataGenerator()->create_course(array('name'=>'Some course', 'category'=>$category->id));

活動を作成する

活動プラグインの中にはインスタンスジェネレータが含まれているものもあります。ジェネレータクラスはplugindirectory/tests/generator/lib.phpで定義されています。

以下、1ページのリソースで新しいコースを作成する例です:

 $course = $this->getDataGenerator()->create_course();
 $generator = $this->getDataGenerator()->get_plugin_generator('mod_page');
 $generator->create_instance(array('course'=>$course->id));

以下、機能的には同じですが、少し短くなります:

 $course = $this->getDataGenerator()->create_course();
 $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));

コーホートを作成する

テンプレート:Moodle 2.4 2.4以降、データジェネレータは新しいコホートの作成に対応しています。

 $cohort = $this->getDataGenerator()->create_cohort();

ユーザ登録の簡略化

テンプレート:Moodle 2.4 標準の登録APIの代わりにデータジェネレータの簡易メソッドを使用できます。これは自己登録および手動登録プラグインと一緒に使用することを意図しています。

$this->getDataGenerator()->enrol_user($userid, $courseid);
$this->getDataGenerator()->enrol_user($userid, $courseid, $teacherroleid);
$this->getDataGenerator()->enrol_user($userid, $courseid, $teacherroleid, 'manual');

尺度を作成する

$this->getDataGenerator()->create_scale();
$this->getDataGenerator()->create_scale(array('name' => $name, 'scale' => $scale, 'courseid' => $courseid, 'userid' => $userid, 'description' => description, 'descriptionformat' => $descriptionformat));

ロールを作成する

$this->getDataGenerator()->create_role();
$this->getDataGenerator()->create_role(array('shortname' => $shortname, 'name' => $name, 'description' => description, 'archetype' => $archetype));

タグを作成する

$this->getDataGenerator()->create_tag();
$this->getDataGenerator()->create_tag(array(
    'userid' => $userid, 
    'rawname' => $rawname,
    'name' => $name, 
    'description' => $description, 
    'descriptionformat' => $descriptionformat,
    'flag' => $flag
));

グループ

グループを作成する

$this->getDataGenerator()->create_group(array('courseid' => $courseid));
$this->getDataGenerator()->create_group(array('courseid' => $courseid, 'name' => $name, 'description' => $description, 'descriptionformat' => $descriptionformat));

グループにユーザを追加する

$this->getDataGenerator()->create_group_member(array('userid' => $userid, 'groupid' => $groupid));
$this->getDataGenerator()->create_group_member(array('userid' => $userid, 'groupid' => $groupid, 'component' => $component, 'itemid' => $itemid));

グルーピングを作成する

$this->getDataGenerator()->create_grouping(array('courseid' => $courseid));
$this->getDataGenerator()->create_grouping(array('courseid' => $courseid, 'name' => $name, 'description' => $description, 'descriptionformat' => $descriptionformat));

グルーピングにグループを追加する

$this->getDataGenerator()->create_grouping_group(array('groupingid' => $groupingid, 'groupid' => $groupid));

リポジトリ

リポジトリインスタンスを作成する

テンプレート:Moodle 2.5 一部のリポジトリプラグインにはインスタンスジェネレータを含むものがあります。ジェネレータクラスは plugindirectory/tests/generator/lib.php で定義されています。

$this->getDataGenerator()->create_repository($type, $record, $options);

リポジトリタイプを作成する

テンプレート:Moodle 2.5 一部のリポジトリプラグインにはタイプジェネレータを含むものがあります。ジェネレータクラスは plugindirectory/tests/generator/lib.php で定義されています。

$this->getDataGenerator()->create_repository_type($type, $record, $options);

評定を作成する

評定カテゴリ

$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid));
$this->getDataGenerator()->create_grade_category(array('courseid' => $courseid, 'fullname' => $fullname));

評定アイテム

$this->getDataGenerator()->create_grade_item();
$this->getDataGenerator()->create_grade_item(array('itemtype' => $itemtype, 'itemname' => $itemname, 'outcomeid' => $outcomeid, 'scaleid' => $scaleid, 'gradetype' => $gradetype));

アウトカム

$this->getDataGenerator()->create_grade_outcome();
$this->getDataGenerator()->create_grade_item(array('fullname' => $fullname));

他のタイプのプラグイン Other types of plugin

テンプレート:Moodle 2.5 他のどのようなタイプのプラグインもジェネレータを持つことができます。ジェネレータクラスではcomponent_generator_baseを継承する必要があります。そして、あなたは $mygenerator = $this->getDataGenerator()->get_plugin_generator($frankenstylecomponentname)でインスタンスを取得できます。

For some types of plugin, like mod documented above, there may be a more specific class than component_generator_base to extend, like testing_module_generator. That will give a consistent set of method names to use. Otherwise, you can create whatever methods you like on your generator, to create the different things you need to work whith.

長いテスト Long tests

All standard test should execute as fast as possible. Tests that take a loner time to execute (>10s) or are otherwise expensive (such as querying external servers that might be flooded by all dev machines) should be execute only when PHPUNIT_LONGTEST is true. This constant can be set in phpunit.xml or directly in config.php.

長いテストデータ Large test data

See advanced_testcase::createXMLDataSet() and advanced_testcase::createCsvDataSet() and related functions there for easier ways to manage large test data sets within files rather than arrays in code. See PHPUnit_integration#Extra_methods

Testing sending of messages

テンプレート:Moodle 2.4 You can temporarily redirect all messages sent via message_send() to a message sink object. This allows developers to verify that the tested code is sending expected messages.

To test code using messaging first disable the use of transactions and then redirect the messaging into a new message sink, you can inspect the results later.

$this->preventResetByRollback();
$sink = $this->redirectMessages();
//... code that is sending messages
$messages = $sink->get_messages();
$this->assertEquals(3, count($messages));
//.. test messages were generated in correct order with appropriate content

Testing sending of emails

Moodle 2.6

You can temporarily redirect emails sent via email_to_user() to a email message sink object. This allows developers to verify that the tested code is sending expected emails.

To test code using messaging first unset 'noemailever' setting and then redirect the emails into a new message sink where you can inspect the results later.

unset_config('noemailever');
$sink = $this->redirectEmails();
//... code that is sending email
$messages = $sink->get_messages();
$this->assertEquals(1, count($messages));

Logstores

You can test events which were written to a logstore, but you must disable transactions, enable at least one valid logstore, and disable logstore buffering to ensure that the events are written to the database before the tests execute.

$this->preventResetByRollback();
set_config('enabled_stores', 'logstore_standard', 'tool_log');
set_config('buffersize', 0, 'logstore_standard');
get_log_manager(true);

Check your coverage

テンプレート:Moodle 3.7 PHPUnit has the ability to generate code coverage information for your unit tests.

Prior to Moodle 3.7, this coverage would load all files and generate coverage for everything regardless of whether that file could be covered at all, or whether it was intentionally covered.

Since Moodle 3.7 the phpunit.xml configuration contains generated coverage include and exclude information for each component.

Generating include and exclude configuration

テンプレート:Moodle 3.11 You can programatically describe which files will be checked for coverage by creating a coverage.php file alongside the tests that you are writing.

Since Moodle 4.0, a default configuration is applied for all plugins and it is not necessary to supply a coverage.php unless you wish to cover additional files.

The coverage.php file allows you to list include and exclude files and folders within the component being tested. All paths specified are relative to the component being tested. For example, when working with mod_forum your code will be in mod/forum, and its unit tests will be in mod/forum/tests/example_test.php. The coverage file for this would be in mod/forum/tests/coverage.php and all paths specified would be relative to mod/forum.

It is possible to specify a combination of included files, included folders, excluded files, and excluded folders. This would allow you, for example, to include the entire classes directory, but exclude.a specific file or folder within it.

The following is an example coverage.php file from mod_forum:

Note: For Moodle versions 3.7 to 3.10, the syntax used was slightly different.

return new class extends phpunit_coverage_info {
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */
    protected $includelistfolders = [
        'classes',
        'externallib.php',
    ];

    /** @var array The list of files relative to the plugin root to include in coverage generation. */
    protected $includelistfiles = [];

    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */
    protected $excludelistfolders = [];

    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */
    protected $excludelistfiles = [];
};

Also, note that you can better define which class or function each test is effectively covering by using the @covers annotation as described in the documention.

Since Moodle 4.0, the following default configuration is applied:テンプレート:Moodle 4.0

return new class extends phpunit_coverage_info {
    /** @var array The list of folders relative to the plugin root to include in coverage generation. */
    protected $includelistfolders = [
        'classes',
        'tests/generator',
    ];

    /** @var array The list of files relative to the plugin root to include in coverage generation. */
    protected $includelistfiles = [
        'externallib.php',
        'lib.php',
        'locallib.php',
        'renderer.php',
        'rsslib.php',
    ];

    /** @var array The list of folders relative to the plugin root to exclude from coverage generation. */
    protected $excludelistfolders = [];

    /** @var array The list of files relative to the plugin root to exclude from coverage generation. */
    protected $excludelistfiles = [];
};

If a coverage.php file already exists, then the defaults will be added to the values already defined.

Best practice

There are several best practices, suggestions, and things to avoid which you should consider when writing unit tests. Some of these are described below.

Code coverage

PHPUnit has the ability to generate code coverage information for your unit tests and this is well supported since.Moodle 3.7. We recommend that you consider checking the coverage of your plugins when you write your code.

We recommend that you explicitly set the @covers annotation as described in the PHPUnit documentation.

Keep use of resetAfterTest to a minimum

Although many of the examples described above use the

resetAfterTest

nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.

Generally speaking you should aim to write code which is mockable, and does not require real fixtures. Use of resetAfterTest will also slow your tests down.

Be careful with shared setUp and instance variables

You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:

  1. If you create any fixtures in the setUp, or call the resetAfterTest function, these fixtures and conditions will apply for _all_ tests in the testsuite. You will not be able to add another test to the suite which does not require these conditions without those conditions being fulfilled anyway. This can lead to slow tests.
  2. PHPUnit creates an instance of each testcase during its bootstrap phase, and does not dispose of it for the lifetime of the test run. Anything which causes data to be stored as instance data within the testcase will be stored in memory until the _entire suite_ completes. This means that any fixture which is setup and not actively discarded will not be garbage collected and lead to memory bloat. In severe cases this can lead to memory exhaustion.


Existing testcases which contain setUp which either generate data, or set resetAfterTest should be phased out, and no new cases should be introduced.

Make use of the dataProvider functionality

The dataProvider functionality of PHPUnit is an extremely powerful and useful feature which allows you to verify a function quickly and easily with a range of different conditions. However, the following rules should be followed when using dataProviders:

  • Keep addition of resettable data requring resetAfterTest to a minimum - this will lead to many slow tests
  • Data providers must not instantiate/create data. Just define it. And then, the test body can proceed with the instantiation/creation. The dataProvider is called after the testSuite is instantiated, but before any tests are run. Each test will run a full setUp and tearDown, which will destroy any data which was created.
/**
 * Test function accepts parameters passed from the specified data provider.
 *
 * @dataProvider foobar_provider
 * @param int $foor
 * @param int $bar
 */
public function test_foobar(int $foo, int $bar) {
    // Perform the tests here.
}

/**
 * Data provider for {@see self::test_foobar()}.
 *
 * @return array List of data sets - (string) data set name => (array) data
 */
public function foobar_provider(): array {
    return [
        'Same numbers' => [
            'foo' => 42,
            'bar' => 42,
        ],
        'Different numbers' => [
            'foo' => 21,
            'bar' => 84,
        ],
    ];
}

Extra test settings

Usually the test should not interact with any external systems and it should work the same on all systems. But sometimes you need to specify some option for connection to external systems or system configuration. It is intentionally not possible to use $CFG settings from config.php.

There are several ways how to inject your custom settings:

  • define test setting constants in your phpunit.xml file
  • define test setting constants in your config.php

These constants may be then used in your test or plugin code.

Upgrading unit tests to work with Moodle 3.11 and up (PHPUnit 9.5)

テンプレート:Moodle 3.11

With Moodle 3.11, PHPUnit was upgraded to 9.5 (from 8.5 being used in previous versions). This was done to better align the testing environment with PHP versions supported by Moodle 3.11 (7.3, 7.4 and 8.0) (see MDL-71036 and linked issues for more details).

While a lot of existing tests will work without modification with PHPUnit 9.5, you will get a good number of deprecation warnings ("W" in the tests output) that should be replaced by their new counterparts as soon as possible, because all those warnings will become errors with next PHPUnit upgrade.

To find more information about the changes coming with PHPUnit 9.5, it's recommended to read the following resources:

A good summary of all the changes and replacements to perform is available in the lib/upgrade.txt file. With main points being:

  • All the changes that were deprecated with PHPUnit 8.5 (see the section below) are now removed and will lead to errors.
  • assertContains() now performs stricter comparison (like assertSame() does). New assertContainsEquals() has been created to provide the old behavior.
  • Changes to the phpunit.xml schema, mostly internal. These only will impact if you are using custom phpunit.xml files:
    • The previous <filter> section is now (better) called <coverage>. And, within it:
      • <whitelist> has been replaced by <include>.
      • <exclude> is not a child of <whitelist> anymore, but of <coverage>.
    • But with implications when defining the coverage information because $whitelistxxx properties used by the coverage.php files have been deprecated, instead use includelistfolders and includelistfiles (to better map the elements in the xml).
  • Warning: It's not possible to run individual test files any more. Use any of the alternative execution methods (filter, suite, config) to specify which tests you want to run. This will be hopefully fixed in MDL-71049 once it has been agreed which the best way to proceed is.
  • Deprecations, deprecations, deprecations. Lots of them in often used assertions: file assertions, regexp assertions, exception expectations... again, note that all them will become errors with the next PHPUnit update, so the recommendation is to update them ASAP.

Finally, it's also a good idea to browse the changes associated with the issue, hopefully with useful explanations in the commit messages.

Upgrading unit tests to work with Moodle 3.10 and up (PHPUnit 8.5)

テンプレート:Moodle 3.10

With Moodle 3.10, PHPUnit was upgraded to 8.5 (from 7.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.10 (7.2, 7.3 and 7.4) and also to provide an easier jump to PHPUnit 9.x that will be needed for Moodle 3.11 (php versions 7.3, 7.4 and 8.0), removing a lot of deprecated stuff in advance. (see MDL-67673 and MDL-64600 for more details).

While 99% of existing tests will work without modification with PHPUnit 8.5, you will get a good number of deprecation warnings ("W" in the tests output) that should be replaced by their new counterparts as soon as possible, because all those warnings will become errors with next PHPUnit upgrade.

To find more information about the changes coming with PHPUnit 8.5, it's recommended to read the following resources:

  • A good article explaining all the main changes in the release.
  • PHPUnit 8 release Announcement.
  • Detailed changelog of the release.
  • Official PHPUnit manual.
  • A good summary of all the changes and replacements to perform is available in the lib/upgrade.txt file. With main points being:
    • Support for PHP 7.0 dropped (because all template methods (setUp(), tearDown()..) now require to return void. This will mostly impact 3rd-part plugins that were still running the same tests against old branches of Moodle with PHP 7.0 support.
    • PHPUnit/DBUnit has been removed are replaced by a lightweight alternative.
    • Deprecations, deprecations, deprecations. Lots of them in often used assertions (assertContains(), assertEquals()...) and also @expectedExceptionXXX annotations. Again, note that all them will become errors with PHPUnit 9.
  • Finally, it's also a good idea to browse the changes associated with the issue, hopefully with useful enough explanations in the commit messages.

Upgrading unit tests to work with Moodle 3.7 and up (PHPUnit 7.5)

テンプレート:Moodle 3.7

With Moodle 3.7, PHPUnit was upgraded to 7.5 (from 6.x being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.7 (7.1, 7.2 and 7.3). (see MDL-65204 and linked issues for more details). While internally a lot of things changed with PHPUnit 7 (PHP 7.1-isms, typed signatures, void returns, assertEquals() changes), thanks to our wrapping layer (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.

To find more information about the changes coming with PHPUnit 7, it's recommended to read the following resources:

Upgrading unit tests to work with Moodle 3.4 and up (PHPUnit 6)

テンプレート:Moodle 3.4

With Moodle 3.4, PHPUnit was upgraded to 6.4 (from 5.5 being used in older version). This was done to better align the testing environment with PHP versions supported by Moodle 3.4 (7.0, 7.1 and 7.2). (see MDL-60611 and linked issues for more details). While internally a lot of things changed with PHPUnit 6 (namespaced classes being the more noticeable), thanks to our wrapping layer (basic and advanced testcases...) impact expected into old existing unit tests is expected to be reduced and upgrades, easy to achieve.

Still, in some cases, it will impossible to maintain compatibility of tests between old (pre 3.4) tests and new ones, especially when direct use of any phpunit class is performed. Luckily, both travis and CI tests will detect this situation and it shouldn't be hard to keep all supported branches in core passing ok. Plugins may be trickier, if the same branch is attempting to work against multiple core branches and they are using some phpunit class directly.

To find more information about the changes coming with PHPUnit 6, it's recommended to read the following resources:

See also