未分類

phpunitでのテストでtimeoutを設定

phpunitの7系のサポート切れ対応で8系へアップグレードを行ったついでに、テストのtimeoutを検知するように設定したのでその手順です。
timeoutの設定のためにはPHP_Invokerパッケージとpcntl拡張モジュールが必要です。
PHP_Invokerパッケージのインストールはcomposerコマンドで行います。
$ composer require phpunit/php-invoker
pcntl は最近のphpであれば最初から入っているかと思います。
下記コマンドを実行すればpcntlが有効か確認できます。
(コマンドラインとphpunitの実行経路が異なる場合はスクリプト上で実行するなどして確認してください)
php -r 'pcntl_signal(SIGALRM, function () {echo "pcntl available!" . PHP_EOL;}, false); pcntl_alarm(1); while (true) {pcntl_signal_dispatch(); sleep(1);}'
pcntl available! と表示されればOKです。自動では終了しないので 「control」 + 「c」 で終了してください。
phpunit.xml にて、enforceTimeLimit="true" を設定します。
デフォルト値が入っていますが、 timeoutForSmallTests="1" も明示的に設定しておくといいでしょう(sec.)。
テストの実行ファイルの方には、クラスのphpDocに @small をつけておきましょう。
@medium や @large にしたいメソッドがあればメソッドのphpDocにつければクラスの定義を上書きします。
※以前は@smallをつけなくても全てsmall扱いでtimeoutの設定が入っていたようですが、今は指定がないと駄目な様子です。
日本語版には表記がありませんが、英語版では

Tests need to be explicitly annotated by either @small@medium, or @large to enable run time limits.

「実行時間の制限を有効にするには、テストに@small、@medium、または@largeのいずれかで明示的に注釈を付ける必要があります。」の表記があります。
参考: https://phpunit.readthedocs.io/ja/latest/risky-tests.html#risky-tests

-未分類