PHPUnit11対応でPHP-CS-Fixerを使ってのAnnotationからAttributeに置換
PHPUnit11でアトリビュート推奨で、アノテーションが使えなくなる件
こんな記事がある
休日に何気なく自分のリポジトリの PHPUnit を 11 にバージョンアップしてみたら全てのテストが動作しなくなり、調べてみたら PHPUnit 11 では PHPDoc のアノテーションは非推奨で、次のバージョンでは利用できなくなるのでアトリビュート (Attribute) を使うことが推奨されている模様。
(;´・ω・) え?マジ?
調べてみると Breaking Change
みたいに大々的に表現しているページなどなく、
PHPUnit10でPHP8のAttributeが使えるようにしといたわ。
PHPUnit11でAnnotation非推奨にするわ。
PHPUnit12でAnnotation完全に使えなくするわ。
と書いてあるだけ。
Metadata
PHPUnit 10 introduced support for PHP 8 attributes to add metadata to test classes and test methods. Previously, annotations in special PHP comments called "docblocks" or "doc-comments" were the only way to add metadata to units of code.
In PHPUnit 11, the annotations that can be used in special PHP comments to add metadata to test classes and test methods are deprecated. Support for these annotations will be removed in PHPUnit 12.
PHPUnit 10 では、PHP 8 の属性をサポートしてテストクラスやテストメソッドにメタデータを追加できるようになりました。これまでは、PHP の特別なコメント "docblocks" や "doc-comments" にアノテーションを書くことで、コードの単位にメタデータを追加していました。
PHPUnit 11 では、PHP の特別なコメントでテストクラスやテストメソッドにメタデータを追加するためのアノテーションは非推奨となります。これらのアノテーションは、PHPUnit 12 ではサポートされなくなります。
('ω') いや気が付かんって。
もしかして: 全部手動で手直しですか?
なんか方法はないものかと検索してみたが
英語圏も含めてこれに関する記事はほぼない。
考え方を変えて、
PHPCSみたいなツールで何とかならないかと模索したところ、
PHP-CS-Fixerであればいけそうだ。
Rule php_unit_attributes
PHPUnit attributes must be used over their respective PHPDoc-based annotations.(PHPUnit 属性は、それぞれの PHPDoc ベースのアノテーションよりも優先して使用しなければなりません。)
これをうまく使って一斉置換する方向で対応したい
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
php-cs-fixer のインストール
既存コードを PHP Coding Standard 対応する目的で作成されたツール
Simfony向けて作られていたが、
長い年月を経ていろんな状況に対応するようになった
すでに使っているのであればそのまま利用で可
新規で使う場合だが、
既存しシステムに組み込むならcomposer.jsonに、
組み込まないならdocker越しかpharファイルを使うのがいい
composer require --dev friendsofphp/php-cs-fixer
curl -L https://cs.symfony.com/download/php-cs-fixer-v3.phar -o php-cs-fixer
chmod a+x php-cs-fixer
docker run -it --rm -v $(pwd):/code ghcr.io/php-cs-fixer/php-cs-fixer:${FIXER_VERSION:-3-php8.3} fix src
Laravel pintを使ってる場合は、
設定を追加するだけでいい。
(Laravel pintはphp-cs-fixerの拡張)
全テスト置換
事前テスト実行
まずは現状のユニットテストが全て通ることを確認
./vendor/bin/phpunit --testdox
> phpunit --testdox
PHPUnit 10.x.x by Sebastian Bergmann and contributors.
Runtime: PHP 8.x.x
Configuration: /var/www/phpunit.xml
............................................................... 63 / 198 ( 31%)
OK, but some tests were skipped!
Tests: 50, Assertions: 100, Skipped: 0.
AnnotationからAttributeへ一斉置換
テストディレクトリを ./tests
とすると
./php-cs-fixer check --rules='php_unit_attributes' ./tests # 該当ファイルのチェック
./php-cs-fixer fix --rules='php_unit_attributes' ./tests # 修正実行
再度テスト実行
結果に変化がなければ完了
./vendor/bin/phpunit --testdox
> phpunit --testdox
PHPUnit 10.x.x by Sebastian Bergmann and contributors.
Runtime: PHP 8.x.x
Configuration: /var/www/phpunit.xml
............................................................... 63 / 198 ( 31%)
OK, but some tests were skipped!
Tests: 50, Assertions: 100, Skipped: 0.
(゚∀゚) やったか!?
差分確認
/**
- * @test
* @testdox Test toArray method with different parameters
- * @dataProvider toArrayDifferentParameters
*/
+ #[\PHPUnit\Framework\Attributes\Test]
+ #[\PHPUnit\Framework\Attributes\DataProvider('toArrayDifferentParameters')]
@test
とか @dataProvider
がattributeに置換されているのがわかる。
ただ、全てのannotationに対応しているのではないようで、
@testdox
は特に変更がない。
(´・ω・`) なんでや
------------------- ↓ 後書はここから ↓-------------------
その他の置換事項
PHPUnit10になってdataProviderがstatic必須になった
ついでに変更するならばruleに php_unit_data_provider_static
を追加する
./php-cs-fixer fix --rules='php_unit_attributes, php_unit_data_provider_static' ./tests
もっと古いテストコードをPHPUnit10に対応する
本稿はPHPUnit11対応ではあるが、
この対応の前に古いコードはPHPUnit10対応しておく方がいい
過去のコードを細心のものにするMigrationルールがあるので、
それのPHPUnit10版である PHPUnit100Migration:risky
をかけておく
./php-cs-fixer fix --rules=@PHPUnit100Migration:risky --allow-risky=yes ./tests
Discussion