こもろぐ @tenkoma

What We Find Changes Who We Become -- Peter Morville著『アンビエント・ファインダビリティ 』

広告:本ブログで紹介している書籍等商品の紹介でAmazonアソシエイトを利用していることがあります。

【追記あり;不具合・修正されそう】PHPUnit 10 から、PhpStorm UIでテスト実行中の出力(echo, var_dump, etc...) が、テストログに出力されない

追記 2023/07/17 不具合としてレポートされ、議論が進んだ結果 10.2.6 (現時点で未リリース)で修正されるようです

追記前の本文

小ネタ。

PHPUnit 10.1 を利用したテストコードをPhpStorm から実行していて、上記の振る舞いの変化に気づいた。どのバージョンで変わったのか、どうすればいいのかを考えてみたい。

PHPUnit 9.6, 10.0 で振る舞いの違いを観察

検証環境は以下の通り

  • PHP 8.2.6
  • PhpStorm 2023.1.2
  • PHPUnit 9.6.8 (9系の最新バージョン), 10.0.0 (10系の最初のバージョン)

サンプルのテストコードは以下である。

<?php  
  
declare(strict_types=1);  
  
namespace Tenkoma\VardumpDuringTestExec\Test\Unit\Case;  
  
use PHPUnit\Framework\TestCase;  
  
class IntegerTest extends TestCase  
{  
    public function testVardump(): void  
    {  
        var_dump(['a' => 'b']);  
    }  
}

PHPUnit 9.6.8では出力された。

PhpStorm + PHPUnit 9.6.8でテスト実行中に var_dump() を実行した

PHPUnit 10.0.0では出力されなかった。

PhpStorm + PHPUnit 10.0.0でテスト実行中に var_dump() を実行した

他の出力形式の場合 (10.0.0)

PhpStorm からPHPUnit を呼び出しているときって、--teamcity ってオプションついてたけど、他の出力形式だとどうなんだろう?

PHPUnit 10.0.0 で、 --teamcity オプションをつけてテスト実行した

--teamcity オプションでテキストで出力させてみた。var_dump() 出力されない。

オプション未指定の場合。

PHPUnit 10.0.0 で、オプション未指定でテスト実行した

--testdox 形式の場合

PHPUnit 10.0.0 で、 --testdox オプションをつけてテスト実行した

var_dump() 出力されない。また、例外がスローされている。(こちらの例外については検証してない)

他の出力形式の場合 (10.1.3)

最新版でも確認してみた。

PHPUnit 10.1.3 で、 --teamcity オプションをつけてテスト実行した

--teamcity の場合、出力されない。

PHPUnit 10.1.3 で、オプション未指定でテスト実行した

未指定だと出力された。(10.0.0 → 10.1.3 のどこかで振る舞いが変わった)

PHPUnit 10.1.3 で、 --testdox オプションをつけてテスト実行した

--testdox でも出力された。(10.0.0 → 10.1.3 のどこかで振る舞いが変わった)

ここまでのまとめ

  • PhpStorm UI から PHPUnit テストケースを実行している場合、10.0以降、テスト実行中の出力(echo, var_dump, etc...)が出力コンソールに表示されなくなる (--teamcityオプションの振る舞いが変わった)
  • オプション未指定、--testdox 指定の場合も 10.0.0 では出力されなくなっていたが、最新の10.1.3 では出力されるようになっている

どうすればいいか

いくつか考えてみた。

開発者テスト(Testing)で var_dump() を使いたくなるのを改善する

アサーションせずに var_dump()したくなるのは、

  • プロダクションコードがテストし辛い状態である
  • テストコードが理解しにくかったり実行し辛い状態である
  • プログラマの実装スキルが不足している状態である
  • プログラマのテストスキルが不足している状態である

などのうちいずれかの兆候もしくは全部の兆候の可能性があるので、開発プロセスやプログラミングに改善の余地がある。はい。 (自己ツッコミ)

Xdebugリモートデバッグ連携して、ブレークさせて、変数を確認する

準備の手間がありますが、便利。

PhpStorm リモートデバッグでブレークして、変数を調べる

出力をアサーションして、Diffウインドウで確認する

  • var_dump() などの出力が、実際にコンソールに出力されないのは、PHPUnitが出力バッファ制御を使っているから
  • 出力バッファ制御を使っている理由は、出力結果のアサーションで利用するため

なので、出力をアサーションすれば、間接的に結果が得られる。

expectOutputString() で、var_dump() 出力をアサーションし、エラー出力を見る

出力バッファに蓄積したデータを取得してアサーションする

前述の方法とほぼ同じ

TestCase::output() で出力バッファのデータを取得してアサーション

PHPUnit 10.1.3 最新版だと、--teamcity 指定しなければ、出力されるので、シェルから実行する

前述の通り、検証した結果 PhpStorm 連携をあきらめれば、var_dump() 出力が得られることがわかったので、--teamcity を指定しなければOK。

ob_flush() を呼び出して、出力バッファに蓄積されたデータを出力する

テスト実行中のデータは出力バッファに蓄積されているので、それを出力させる。 この方法は、テストコードに expectOutputString() アサーションがあると、Failする可能性がある。