0

PHPUnit でいくつかのテストをプログラミングしていますが、最近、次のフラグ オプションに出会いました。テストスイート。ただし、次のような例外が常に発生します。

PHPUnit_Framework_Exception: stty: Standard Input: Invalid Argument

または時々:

PHPUnit_Framework_Exception: Notice: Constant PEAR_ERROR_RETURN already defined in /usr/share/php/PEAR.php on line 25
Notice: Constant PEAR_ERROR_PRINT already defined in /usr/share/php/PEAR.php on line 26
Notice: Constant PEAR_ERROR_TRIGGER already defined in /usr/share/php/PEAR.php on line 27
Notice: Constant PEAR_ERROR_DIE already defined in /usr/share/php/PEAR.php on line 28
Notice: Constant PEAR_ERROR_CALLBACK already defined in /usr/share/php/PEAR.php on line 29
Notice: Constant PEAR_ERROR_EXCEPTION already defined in /usr/share/php/PEAR.php on line 34
Notice: Constant PEAR_ZE2 already defined in /usr/share/php/PEAR.php on line 37
Notice: Constant OS_WINDOWS already defined in /usr/share/php/PEAR.php on line 44
Notice: Constant OS_UNIX already defined in /usr/share/php/PEAR.php on line 45
Notice: Constant PEAR_OS already defined in /usr/share/php/PEAR.php on line 46

最初の例外は、プロセス分離のフラグを有効にしたときにのみ発生しますが、私はそれを持っていませんが、テストは問題なくスムーズに実行されます。2番目の例外は、最初はインクルージョンの競合が原因であると考えていましたが、調べてすべてのインクルードを include_once に変更した後も、例外が引き続き発生します。

どんな助けでもいただければ幸いです。

4

2 に答える 2

1

私はこの問題を深く掘り下げました。PHPUnit 3.7 を使用している前提で説明します。

プロセス分離を使用すると、PHPUnit は引き続きグローバル状態を子プロセスに挿入します。この時点で、preserveGlobalState をデフォルトでオンにすることは、runInSeparateProcess の意図と矛盾するという反対意見を聞くかもしれません。phpunit.xml にグローバル変数/定数/includePath を定義するセクションがあることに気付くまで、同じ方法でしたが、preserveGlobalState がなければ、これらの設定は決して子プロセスになりません。したがって、ほとんどの場合、子プロセスへのグローバル状態の注入が必要であると確信しています。必要なことは、このグローバル状態がテストを実行するのに十分クリーンであることを確認することだけです。

Sebastian Bergmann は、globals/constants/required ファイルをエクスポートし、それを Smarty テンプレートに入れるコードをいくつか作成しました。このテンプレートは、chlid プロセスの PHP スクリプトになります。しかし、彼は 1 つの小さな間違いを犯しました (私の見解では): 彼は必要なファイルの後ではなく、前に定数をロードしました。そして、これは大きな違いを生みます!ここに例があります:

必要なファイル.php:

<?php

define("SOME_CONSTANT", true);

class RequiredClass
 {
 }

?>

このファイルが親 PHPUnit プロセスによってロードされると、定数が定義され、requiredfile.php がインクルード ファイルのリストに追加されます。

次に、PHPUnit は基本的に次のような子用の PHP スクリプトを作成します。

<?php

define("SOME_CONSTANT", true);

require_once "requiredfile.php";

?>

もちろん、このエラーがテスト コードではなく、PHPUnit が生成したコードによってトリガーされたことがわからないため、PHPUnit によって例外に変換されたエラー (既に定義されている定数) が PHP によってトリガーされます。

ただし、このコードの定数定義には if (defined()) があるため、定数の定義を必要なファイルの後に置くと、定数の再定義は発生せず、エラーは発生しません。

失敗した PHPT テストの主な原因は PEAR.php であり、PHPUnit は PEAR の RunTest を使用するため、これを回避することはできません。したがって、PHPUnit 3.7 で Smarty テンプレートを修正しない限り、プロセス分離を使用するテストと一緒に PHPT テストを実行することはできません。

それで、あなたは何をする必要がありますか?簡単!PHPUnit/Framework/Process/TestCaseMethod.tpl.dist に移動し、 {constants} と {included_files} を交換します。これは、特に PHPUnit ファイルを変更できない場合は、誰にとっても最善の解決策ではない可能性があります。しかし、私は個人的にこれを PHPUnit のバグと考えているため、そのような修正は保証されています。

于 2014-10-20T17:58:39.563 に答える
0

追加してみてください:

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */

コマンドラインオプションを使用するのではなく、テストの上のPHPDocに。フラグは、テスト間でグローバル変数を保持している可能性があります。

于 2013-07-27T05:48:37.990 に答える