追記 2023/07/17 不具合としてレポートされ、議論が進んだ結果 10.2.6 (現時点で未リリース)で修正されるようです
- 報告されたPR: Proposal for progress output when using teamcity. #5367 by SakiTakamachi
- 実際に修正されたコミット: Closes #5445 by sebastianbergmann
追記前の本文
小ネタ。
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では出力された。
PHPUnit 10.0.0では出力されなかった。
他の出力形式の場合 (10.0.0)
PhpStorm からPHPUnit を呼び出しているときって、--teamcity
ってオプションついてたけど、他の出力形式だとどうなんだろう?
--teamcity
オプションでテキストで出力させてみた。var_dump()
出力されない。
オプション未指定の場合。
--testdox
形式の場合
var_dump()
出力されない。また、例外がスローされている。(こちらの例外については検証してない)
他の出力形式の場合 (10.1.3)
最新版でも確認してみた。
--teamcity
の場合、出力されない。
未指定だと出力された。(10.0.0 → 10.1.3 のどこかで振る舞いが変わった)
--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リモートデバッグ連携して、ブレークさせて、変数を確認する
準備の手間がありますが、便利。
出力をアサーションして、Diffウインドウで確認する
var_dump()
などの出力が、実際にコンソールに出力されないのは、PHPUnitが出力バッファ制御を使っているから- 出力バッファ制御を使っている理由は、出力結果のアサーションで利用するため
なので、出力をアサーションすれば、間接的に結果が得られる。
出力バッファに蓄積したデータを取得してアサーションする
前述の方法とほぼ同じ
PHPUnit 10.1.3 最新版だと、--teamcity
指定しなければ、出力されるので、シェルから実行する
前述の通り、検証した結果 PhpStorm 連携をあきらめれば、var_dump()
出力が得られることがわかったので、--teamcity
を指定しなければOK。
ob_flush()
を呼び出して、出力バッファに蓄積されたデータを出力する
テスト実行中のデータは出力バッファに蓄積されているので、それを出力させる。
この方法は、テストコードに expectOutputString()
アサーションがあると、Failする可能性がある。