Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

PHPUnit 11 概論

02
June 22, 2024

PHPUnit 11 概論

2024/06/22 PHPカンファレンス福岡 2024で使用したスライドです
https://fortee.jp/phpcon-fukuoka-2024/proposal/3a90fed9-26cb-4f09-8294-2af024ccee6a

02

June 22, 2024
Tweet

More Decks by 02

Other Decks in Technology

Transcript

  1. © 2012-2024 BASE, Inc. #phpconfuk BASE, Inc. BASE BANK 振込申請チーム

    Engineering Program Manager / フルサイクルエンジニア PHPカンファレンス2024 実行委員長 02 大津 和槻(おおつ かずき) :@cocoeyes02 自己紹介
  2. © 2012-2024 BASE, Inc. #phpconfuk 今回話す内容 4 • PHP 8.2以上が必須に

    • テストスタブでexpectsが非推奨に • TestCase / MockBuilderクラスのメソッドがいくつか非推奨に • コメント(アノテーション)を使用したメタデータが非推奨に • dataprovider周りの仕様変更 • 新しく追加されたアサーション、オプション
  3. © 2012-2024 BASE, Inc. #phpconfuk テストスタブでexpectsが非推奨に 9 おさらい:PHPUnitのテストダブルは2種類存在します。 (詳細はドキュメントへ) •

    テストスタブ ◦ あらかじめ決められた戻り値や例外などを返すオブジェクト ◦ 代表的なメソッド:willreturn、willThrowException • モックオブジェクト ◦ メソッドの呼び出し回数や引数など呼び出され方を検証するオブ ジェクト ◦ テストスタブのメソッドも使える ◦ 代表的なメソッド:expects、with
  4. © 2012-2024 BASE, Inc. #phpconfuk テストスタブでexpectsが非推奨に 10 おさらい:PHPUnitのテストダブルは2種類存在します。 (詳細はドキュメントへ) •

    テストスタブ ◦ あらかじめ決められた戻り値や例外などを返すオブジェクト ◦ 代表的なメソッド:willreturn、willThrowException • モックオブジェクト ◦ メソッドの呼び出し回数や引数など呼び出され方を検証するオブ ジェクト ◦ テストスタブのメソッドも使える ◦ 代表的なメソッド:expects、with
  5. © 2012-2024 BASE, Inc. #phpconfuk テストスタブでexpectsが非推奨に 11 <?php // これはOK

    $mock = $this->createMock(Observer::class); $mock->expects($this->once()) ->method('update') ->with($this->identicalTo('something')); <?php // これはNG $stub = $this->createStub(Observer::class); $stub->expects($this->once()) ->method('doSomething') ->willReturn('foo'); テストスタブで、expectsメソッドが非推奨になりました。 →メソッドの呼び出し回数を検証するのは、モックオブジェクトの役割のため PHPUnit11で非推奨、PHPUnit12で削除になるようです。
  6. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 13

    TestCase • iniSet() • setLocale() • createTestProxy() • getMockForTrait() • getObjectForTrait() • getMockForAbstractClass() • returnValue() • onConsecutiveCalls() • returnValueMap() • returnArgument() • returnSelf() • returnCallback()
  7. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 14

    TestCase • iniSet() • setLocale() • createTestProxy() • getMockForTrait() • getObjectForTrait() • getMockForAbstractClass() • returnValue() • onConsecutiveCalls() • returnValueMap() • returnArgument() • returnSelf() • returnCallback()
  8. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 17

    (前略) このgetMockForTrait()メソッドは、指定された特性を使用する空のクラ スのモック オブジェクトを返します。 指定された特性のすべての抽象メソッドがモック化されます。これによ り、特性の具体的なメソッドをテストできます。 何かをテストするためにgetMockForTrait()を使用する必要があるのは、 ほとんどの場合、コードの臭いが発生します。つまり、テスト対象システ ムのソフトウェア設計に何か問題があるということです。 (後略) https://github.com/sebastianbergmann/phpunit/issues/5243
  9. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 18

    何かをテストするためにgetMockForTrait()を使用する必要があるのは、 ほとんどの場合、コードの臭いが発生します。 つまり、テスト対象システムのソフトウェア設計に何か問題があるという ことです。 https://github.com/sebastianbergmann/phpunit/issues/5243
  10. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 19

    何かをテストするためにgetMockForTrait() / getObjectForTrait()を使 用する必要があるのは、ほとんどの場合、コードの臭いが発生します。 つまり、テスト対象システムのソフトウェア設計に何か問題があるという ことです。 https://github.com/sebastianbergmann/phpunit/issues/5244 https://github.com/sebastianbergmann/phpunit/issues/5243
  11. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 20

    何かをテストするためにgetMockForTrait() / getObjectForTrait() / getMockForAbstractClass()を使用する必要があるのは、ほとんどの場 合、コードの臭いが発生します。 つまり、テスト対象システムのソフトウェア設計に何か問題があるという ことです。 https://github.com/sebastianbergmann/phpunit/issues/5245 https://github.com/sebastianbergmann/phpunit/issues/5244 https://github.com/sebastianbergmann/phpunit/issues/5243
  12. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 21

    何かをテストするためにgetMockForTrait() / getObjectForTrait() / getMockForAbstractClass()を使用する必要があるのは、ほとんどの場 合、コードの臭いが発生します。 つまり、テスト対象システムのソフトウェア設計に何か問題があるという ことです。 https://github.com/sebastianbergmann/phpunit/issues/5245 https://github.com/sebastianbergmann/phpunit/issues/5244 https://github.com/sebastianbergmann/phpunit/issues/5243 😭
  13. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 22

    TestCase • iniSet() • setLocale() • createTestProxy() • getMockForTrait() • getObjectForTrait() • getMockForAbstractClass() • returnValue() • onConsecutiveCalls() • returnValueMap() • returnArgument() • returnSelf() • returnCallback()
  14. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 25

    MockBuilder • enableAutoload() • disableAutoload() • enableArgumentCloning() • disableArgumentCloning() • allowMockingUnknownTypes() • disallowMockingUnknownTypes() • enableProxyingToOriginalMethods() • disableProxyingToOriginalMethods() • getMockForAbstractClass() • getMockForTrait() • setProxyTarget() • addMethods()
  15. © 2012-2024 BASE, Inc. #phpconfuk TestCase / MockBuilderクラスの メソッドがいくつか非推奨に 26

    MockBuilder • enableAutoload() • disableAutoload() • enableArgumentCloning() • disableArgumentCloning() • allowMockingUnknownTypes() • disallowMockingUnknownTypes() • enableProxyingToOriginalMethods() • disableProxyingToOriginalMethods() • getMockForAbstractClass() • getMockForTrait() • setProxyTarget() • addMethods()
  16. © 2012-2024 BASE, Inc. #phpconfuk コメント(アノテーション)を使用した メタデータが非推奨に 28 実はPHPUnit 10のときに、予告されていた変更です。

    予告通り、PHPUnit11で非推奨になりました。 https://speakerdeck.com/cocoeyes02/introduction-of-phpunit-10?slide=38
  17. © 2012-2024 BASE, Inc. #phpconfuk コメント(アノテーション)を使用した メタデータが非推奨に 29 <?php declare(strict_types=1);

    namespace example; use PHPUnit\Framework\TestCase; /** * @dataProvider Foo::dataProviderMethod() */ final class FooTest extends TestCase { // ... } 例:DataProviderを呼び出す場合(非推奨)
  18. © 2012-2024 BASE, Inc. #phpconfuk コメント(アノテーション)を使用した メタデータが非推奨に 30 <?php declare(strict_types=1);

    namespace example; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\DataProvider; #[DataProvider(Foo::class, 'dataProviderMethod')] final class FooTest extends TestCase { // ... } 例:DataProviderを呼び出す場合(今後の書き方)
  19. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 32 以下の条件に当てはまるDataProviderが、エラーになるようになりました。 • staticではない

    • publicではない • 引数を必要とする 逆にいえば、下記のような形式のDataProviderでないとダメということですね。 public static XXX() {} ちなみにPHPUnit10の時点では、まだ非推奨になっているだけでした。
  20. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 34 PHPUnit 10では、dataproviderとテストメソッドの引数順を揃える必要があります。 (’c’と書かれていても配列の1番目あるから、1番目の引数である

    $a に代入される) <?php public static function providerMethod() { return [ ['a' => 1, 'b' => 2, 'c' => 3], // OK ['c' => 3, 'a' => 2, 'b' => 1], // NG ['c' => 1, 'hoge' => 2, 'b' => 3], // OK ]; } #[DataProvider('providerMethod')] public function testAdd($a, $b, $c): void { $this->assertEquals($c, $a + $b); }
  21. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 35 PHPUnit 10では、dataproviderとテストメソッドの引数順を揃える必要があります。 (’c’と書かれていても配列の1番目あるから、1番目の引数である

    $a に代入される) <?php public static function providerMethod() { return [ ['a' => 1, 'b' => 2, 'c' => 3], // OK ['c' => 3, 'a' => 2, 'b' => 1], // NG ['c' => 1, 'hoge' => 2, 'b' => 3], // OK ]; } #[DataProvider('providerMethod')] public function testAdd($a, $b, $c): void { $this->assertEquals($c, $a + $b); }
  22. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 36 PHPUnit 11では、引数順を気にする必要がなくなりました。 ただし、テストメソッドに存在しない引数を指定した場合はエラーになります。

    <?php public static function providerMethod() { return [ ['a' => 1, 'b' => 2, 'c' => 3], // OK ['c' => 3, 'a' => 2, 'b' => 1], // OK ['c' => 1, 'hoge' => 2, 'b' => 3], // NG ]; } #[DataProvider('providerMethod')] public function testAdd($a, $b, $c): void { $this->assertEquals($c, $a + $b); }
  23. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 37 PHPUnit 11では、引数順を気にする必要がなくなりました。 ただし、テストメソッドに存在しない引数を指定した場合はエラーになります。

    <?php public static function providerMethod() { return [ ['a' => 1, 'b' => 2, 'c' => 3], // OK ['c' => 3, 'a' => 2, 'b' => 1], // OK ['c' => 1, 'hoge' => 2, 'b' => 3], // NG ]; } #[DataProvider('providerMethod')] public function testAdd($a, $b, $c): void { $this->assertEquals($c, $a + $b); }
  24. © 2012-2024 BASE, Inc. #phpconfuk dataprovider周りの仕様変更 38 PHPUnit 11では、引数順を気にする必要がなくなりました。 ただし、テストメソッドに存在しない引数を指定した場合はエラーになります。

    <?php public static function providerMethod() { return [ ['a' => 1, 'b' => 2, 'c' => 3], // OK ['c' => 3, 'a' => 2, 'b' => 1], // OK ['c' => 1, 'hoge' => 2, 'b' => 3], // NG ]; } #[DataProvider('providerMethod')] public function testAdd($a, $b, $c): void { $this->assertEquals($c, $a + $b); } ❌
  25. © 2012-2024 BASE, Inc. #phpconfuk 新しく追加された アサーション、オプション 40 • assertArrayIsEqualToArrayIgnoringListOfKeys

    • assertArrayIsIdenticalToArrayIgnoringListOfKeys ◦ 配列のうち指定したキー名以外の値を、緩やかな比較(==)| 厳密比較 (===)する $this->assertArrayIsEqualToArrayIgnoringListOfKeys( [ 'hoge' => '123', 'foo' => 'bar', ], [ 'hoge' => '456', 'foo' => 'baz', ], [ 'hoge',] ); // Failuresになるのは'foo'だけ
  26. © 2012-2024 BASE, Inc. #phpconfuk 新しく追加された アサーション、オプション 41 • assertArrayIsEqualToArrayOnlyConsideringListOfKeys

    • assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys ◦ 配列のうち指定したキー名のみの値を、緩やかな比較(==)| 厳密比較 (===)する $this->assertArrayIsEqualToArrayOnlyConsideringListOfKeys( [ 'hoge' => '123', 'foo' => 'bar', ], [ 'hoge' => '456', 'foo' => 'baz', ], [ 'hoge',] ); // Failuresになるのは'hoge'だけ
  27. © 2012-2024 BASE, Inc. #phpconfuk 新しく追加された アサーション、オプション 42 • assertObjectNotEquals

    ◦ オブジェクトに定義済みのメソッド(デフォルトはequals())の返り値同 士で、厳密比較(===)して一致していないことを検証する <?php declare(strict_types=1); final class Email { public function __construct( private string $email ) {} public function equals(self $other): bool { return $this->asString() === $other->asString(); } } <?php $a = new Email('[email protected]'); $b = new Email('[email protected]'); $c = new Email('[email protected]'); // False $this->assertObjectNotEquals($a, $b); // True $this->assertObjectNotEquals($a, $c);
  28. © 2012-2024 BASE, Inc. #phpconfuk 新しく追加された アサーション、オプション 43 • --exclude-filter

    ◦ --filterオプションの除外バージョン ◦ パターン(ファイル名やテスト名など)に一致したテスト以外を 実行する • --list-test-files ◦ 実行できるテストファイル一覧を表示する
  29. © 2012-2024 BASE, Inc. #phpconfuk 最後に 44 今回どのChangeLogに触れたかは、スライドの最後に載せています。 時間の都合で一部のみの解説になりましたが、解説していない機能や変更があります! •

    xml形式の構成ファイルについての変更 • getMockBuilderが消えそうになった話 • TestCaseクラスで多くのメソッドにfinal / protected修飾子がついた 前回のPHPUnit 10概論の話を含め、「PHPUnit10(または11)で非推奨になって、 PHPUnit11(または12)で使えなくなる」の機能がたくさんあると感じました。 バージョンを上げる作業をする時に書き直す作業が減るきっかけにもなるので、 将来的に使えなくなる書き方は、避けたほうが無難ですね。(自動置換ツール欲しい)
  30. © 2012-2024 BASE, Inc. #phpconfuk 最後に バックエンド エンジニア SRE フロントエンド

    エンジニア セキュリティ エンジニア QA エンジニア データ エンジニア etc… We are hiring! https://binc.jp/jobs
  31. © 2012-2024 BASE, Inc. #phpconfuk 今回触れたChangeLog 48 TestCase / MockBuilderクラスのメソッドがいくつか非推奨に

    • #5214: TestCase::iniSet() (this method was already soft-deprecated in PHPUnit 10) • #5216: TestCase::setLocale() (this method was already soft-deprecated in PHPUnit 10) • #5240: TestCase::createTestProxy() (this method was already soft-deprecated in PHPUnit 10) • #5241: TestCase::getMockForAbstractClass() (this method was already soft-deprecated in PHPUnit 10) • #5242: TestCase::getMockFromWsdl() (this method was already soft-deprecated in PHPUnit 10) • #5243: TestCase::getMockForTrait() (this method was already soft-deprecated in PHPUnit 10) • #5244: TestCase::getObjectForTrait() (this method was already soft-deprecated in PHPUnit 10) • #5423: TestCase::returnValue(), TestCase::onConsecutiveCalls(), TestCase::returnValueMap(), TestCase::returnArgument(), TestCase::returnSelf(), and TestCase::returnCallback() (these methods were already soft-deprecated in PHPUnit 10)
  32. © 2012-2024 BASE, Inc. #phpconfuk 今回触れたChangeLog 49 TestCase / MockBuilderクラスのメソッドがいくつか非推奨に

    • #5305: MockBuilder::getMockForAbstractClass() (this method was already soft-deprecated in PHPUnit 10) • #5306: MockBuilder::getMockForTrait() (this method was already soft-deprecated in PHPUnit 10) • #5307: MockBuilder::enableProxyingToOriginalMethods(), MockBuilder::disableProxyingToOriginalMethods(), and MockBuilder::setProxyTarget() (these methods were already soft-deprecated in PHPUnit 10) • #5308: MockBuilder::allowMockingUnknownTypes() and MockBuilder::disallowMockingUnknownTypes() (these methods were already soft-deprecated in PHPUnit 10) • #5309: MockBuilder::enableAutoload() and MockBuilder::disableAutoload() (these methods were already soft-deprecated in PHPUnit 10) • #5315: MockBuilder::enableArgumentCloning() and MockBuilder::disableArgumentCloning() (these methods were already soft-deprecated in PHPUnit 10) • #5320: MockBuilder::addMethods() (this method was already soft-deprecated in PHPUnit 10)
  33. © 2012-2024 BASE, Inc. #phpconfuk 今回触れたChangeLog 51 dataprovider周りの仕様変更 • #5100:

    Support for non-static data provider methods, non-public data provider methods, and data provider methods that declare parameters • #5225: Allow providing named arguments from a data provider
  34. © 2012-2024 BASE, Inc. #phpconfuk 今回触れたChangeLog 52 新しく追加されたアサーション、オプション • #5629:

    --exclude-filter CLI option for excluding tests from execution • #5642: --list-test-files CLI option to print the list of test files • #5600: Assertions for comparing arrays while ignoring a specified list of keys • #5811: assertObjectNotEquals()