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

提供:MoodleDocs
移動先:案内検索
編集の要約なし
編集の要約なし
330行目: 330行目:
[https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnitドキュメンテーション]で説明されているように@coversアノテーションを明示的に設定することを推奨します。
[https://phpunit.readthedocs.io/en/9.5/annotations.html#appendixes-annotations-covers-tables-annotations PHPUnitドキュメンテーション]で説明されているように@coversアノテーションを明示的に設定することを推奨します。


==resetAfterTestの使用を最小限に留める Keep use of resetAfterTest to a minimum==
==resetAfterTestの使用を最小限に留める==
Although many of the examples described above use the <syntaxhighlight lang="php">resetAfterTest</syntaxhighlight> nomenclature to reset the database and filesystem after your test completes, you should ideally not use this unless you have to.
上で説明した例の多くでは<syntaxhighlight lang="php">resetAfterTest</syntaxhighlight>という命名法を用いてテスト終了後にデータベースおよびファイルシステムをリセットしていますが、 必要がなければこれを使用しないのが理想的でしょう。
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.
上で説明した例の多くは<syntaxhighlight lang="php">resetAfterTest</syntaxhighlight>という命名法を用いてテスト終了後にデータベースおよびファイルシステムをリセットしていますが、 必要がなければこれを使用しないのが理想的でしょう。
一般的に言えばモック可能で実際の修正を必要としないコードを書くことを目指すべきでしょう。resetAfterTestを使用した場合、テストの速度が低下します。
一般的に言えばモック可能で実際の修正を必要としないコードを書くことを目指すべきでしょう。resetAfterTestを使用した場合、テストの速度が低下します。


==Be careful with shared setUp and instance variables==
==共有のsetUpおよびインスタンス変数の扱いに注意する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:
You should be careful of how you create and use instance variables in PHPUnit tests for two main reasons:
# 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.
# 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.

2022年5月30日 (月) 15:05時点における版

テンプレート: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();

あなたはユーザアカウントのプロパティも指定できます。例えば以下のようになります:

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

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

 $this->setUser($user1);

ゲストおよび管理者アカウントにはショートカットメソッドがあります:

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

現在のユーザをログインなしにするためにNullを使用できます:

 $this->setUser(null);

コースカテゴリを作成する

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

コースを作成する

 $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));

他のタイプのプラグイン

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

いくつかのタイプのプラグインのために上で文書化されたmodのように拡張するcomponent_generator_baseよりも、さらに特定のクラス、例えばtesting_module_generatorのようなクラスがあるかもしれません、そのクラスでは使用すべきメソッド名の一貫したセットを与えることでしょう。そうでなければ、あなたが作業する必要のある異なったものを作成するためにジェネレータ上であなたが好きなどのようなメソッドでも作成できます。

長いテスト Long tests

標準的なテストはすべて可能な限り高速に実行されるべきです。実行に時間を要するもの (10秒以上) または負荷のかかるもの (たとえば外部のサーバへの問い合わせに開発マシンが殺到してしまった場合等) はPHPUNIT_LONGTESTがtrueの場合のみ実行されるようにしなければなりません。この定数はphpunit.xmlあるいはconfig.phpで直接設定できます。

長いテストデータ

大きなテストデータセットをコード内の配列としてではなく、ファイルとして簡単に管理する方法に関して、advanced_testcase::createXMLDataSet()、advanced_testcase::createCsvDataSet()および関連関数を参照してください。詳細はPHPUnit_integration#Extra_methods]]を参照してください。

メッセージ送信テスト

テンプレート:Moodle 2.4 あなたはmessage_send()で送信されたすべてのメッセージを一時的にメッセージシンクオブジェクトにリダイレクトできます。これにより開発者はテストしたコードが期待どおりのメッセージを送信しているかどうか確認できます。

メッセージングを使ったコードをテストする場合、まずトランザクションを無効にしてください。 メッセージングを新しいメッセージシンクにリダイレクトすることにより、 後で結果を確認できます。

$this->preventResetByRollback();
$sink = $this->redirectMessages();
//... メッセージを送信するコード
$messages = $sink->get_messages();
$this->assertEquals(3, count($messages));
//.. . テストメッセージが正しい順序で、適切な内容で生成されました。

メール送信テスト

Moodle 2.6

あなたはemail_to_user()で送信されたメールを一時的にemail message sinkオブジェクトにリダイレクトできます。これにより、開発者はテストしたコードが期待通りのメールを送信しているかどうかを確認できます。

メッセージングを使ったコードをテストする場合、まず「noemailever」の設定を解除してください。メールを新しいメッセージシンクにリダイレクトすることにより、 後で結果を確認できます。

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

ログストア

あなたはログストアに書き込まれたイベントをテストできますが、テスト実行の前にイベントがデータベースに書き込まれるようトランザクションを無効にして、少なくとも1つの有効なログストアを有効にした上で、ログストアのバッファリングを無効にする必要があります。

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

あなたのカバレッジを確認する

テンプレート:Moodle 3.7 PHPUnit には単体テストのコードカバレッジ情報を生成する機能があります。

Moodle 3.7以前、このカバレッジはすべてのファイルを読み込み、そのファイルが全くカバーできないかどうか、または意図的にカバーされているかどうかに関係なく、すべてに対してカバレッジを生成していました。

Moodle 3.7以降、「phpunit.xml」設定には各コンポーネントの生成されたカバレッジインクルードおよびエクスクルード情報が含まれています。

インクルードおよびエクスクルード設定を生成する

テンプレート:Moodle 3.11 あなたが書いているテストと一緒にcoverage.phpファイルを作成することにより、どのファイルがカバレッジのためにチェックされるかプログラム的に記述できます。

Moodle 4.0以降、デフォルト設定がすべてのプラグインに適用されるため、あなたが追加ファイルをカバーしたい場合を除き、coverage.phpを提供する必要はありません。

coverage.phpファイルではテスト対象のコンポーネントに含まれるファイルおよびフォルダを一覧表示できます。指定されたすべてのパスはテストされるコンポーネントからの相対パスです。例えば「'mod_forum」を扱う場合、あなたのコードは「'mod_forum」に置かれます。また、ユニットテストは「mod/forum/tests/example_test.php」にあります。カバレッジファイルは「mod/forum/tests/coverage.php」にあります。指定されたすべてのパスは「mod/forum」からの相対パスとなります。

含まれるファイル、含まれるフォルダ、除外されるファイルおよび除外されるフォルダを組み合わせて指定できます。これにより、例えば「classes」ディレクトリ全体を含み、その中の特定のファイルまたはフォルダを除外できます。

以下「mod_forum」のcoverage.phpの例です:

メモ: Moodleバージョン3.7および3.10では使用される文法が少しだけ異なります。

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. また、@coversアノテーションの使用により、各テストがどのクラスまたは関数を効果的にカバーしているかより明確に定義できることに留意してください。詳細はドキュメンテーションをご覧ください。

Moodle 4.0以降、以下のデフォルト設定が適用されます:テンプレート: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 = [];
};

すでにcoverage.phpファイルが存在する場合、定義済みの値にデフォルトが追加されます。

ベストプラクティス

あなたが単体テストを書く場合に考慮すべきいくつかのベストプラクティス、提案、そして避けるべき点があります。そのいくつかを以下に説明します。

コードカバレッジ

PHPUnitには単体テストのコードカバレッジ情報を生成する機能があり、Moodle 3.7からサポートされています。コードを書く場合、あなたのプラグインのカバレッジのチェックを検討することをお勧めします。

PHPUnitドキュメンテーションで説明されているように@coversアノテーションを明示的に設定することを推奨します。

resetAfterTestの使用を最小限に留める

上で説明した例の多くでは

resetAfterTest

という命名法を用いてテスト終了後にデータベースおよびファイルシステムをリセットしていますが、 必要がなければこれを使用しないのが理想的でしょう。

一般的に言えばモック可能で実際の修正を必要としないコードを書くことを目指すべきでしょう。resetAfterTestを使用した場合、テストの速度が低下します。

共有のsetUpおよびインスタンス変数の扱いに注意する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