2012-03-16 28 views
72

PHPunitを使用してカスタムヘッダを出力するクラスをテストしようとしています。PHPUnitでPHPヘッダをテストする

問題は、私のマシン上でこの:

<?php 

class HeadersTest extends PHPUnit_Framework_TestCase { 

    public function testHeaders() 
    { 
     ob_start(); 

     header('Location: foo'); 
     $headers_list = headers_list(); 
     header_remove(); 

     ob_clean(); 

     $this->assertContains('Location: foo', $headers_list); 
    } 
} 

かさえ、この:

<?php 

class HeadersTest extends PHPUnit_Framework_TestCase { 

    public function testHeaders() 
    { 
     ob_start(); 

     header('Location: foo'); 
     header_remove(); 

     ob_clean(); 
    } 
} 

リターンこのエラーを:何か他のものがあるかのように

[email protected] [~/test]# phpunit --verbose HeadersTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann. 

E 

Time: 0 seconds, Memory: 2.25Mb 

There was 1 error: 

1) HeadersTest::testHeaders 
Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173) 

/test/HeadersTest.php:9 

FAILURES! 
Tests: 1, Assertions: 0, Errors: 1. 

これが見えます他のファイルが含まれていないにもかかわらずテストが実行される前に端末に出力し、他のキャラクタがないPHPタグの開始前に。これを引き起こしているPHPunitの中に何かがありますか?

問題は何か?

+11

これに興味のある他の人がいれば、これをカバーしたかっただけです。 headers_list()は(PHP CLIを使用する)PHPunitの実行中には動作しませんが、代わりにxdebug_get_headers()が機能します。 – titel

答えて

103

PHPUnitはヘッダを画面に表示し、その時点でヘッダを追加できないという問題があります。

回避策は、テストを独立したプロセスで実行することです。

$ phpunit FooTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann. 

. 

Time: 1 second, Memory: 9.00Mb 

OK (1 test, 0 assertions) 

キーが@runInSeparateProcess注釈である:ここではこれがになります

<?php 

class FooTest extends PHPUnit_Framework_TestCase 
{ 
    /** 
    * @runInSeparateProcess 
    */ 
    public function testBar() 
    { 
     header('Location : http://foo.com'); 
    } 
} 

例です。

あなたは〜4.1か何かのPHPUnitを使用している場合は、エラーを取得:

PHP Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in -:378 
Stack trace: 
#0 {main} 
    thrown in - on line 378 

Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 

Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 

Call Stack: 
    0.0013  582512 1. {main}() -:0 

はそれを修正するためにあなたのブートストラップファイルに以下を追加してみてください。別々にテストを実行しているが、

<?php 
if (!defined('PHPUNIT_COMPOSER_INSTALL')) { 
    define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/path/to/composer/vendors/dir/autoload.php'); 
} 
+7

これはいくつかのdefine()ステートメントがあるとエラーを引き起こします PHPUnit_Framework_Exception:Notice:定数xyzはすでに定義されています – mebjas

+1

@mebjasそれは無関係と聞こえます。 – SamHennessy

+0

私はphpunitでヘッダをテストし、私のコードに 'define'文がある場合、このメソッドはエラーを引き起こします。 – mebjas

88

をプロセスは問題を解決しますが、大規模な一連のテストを実行すると顕著なオーバーヘッドがあります。

私の修正はそうのように、stderrにPHPUnitの出力を指示することでした。問題を解決し、それはまた、あなたがすべてのオカレンスをラッパー関数を作成し、交換する必要がないことを意味する必要があり

phpunit --stderr <options> 

あなたのコード。

+3

ブリリアント!私のコードに変更はなく、別のプロセスもなく、動作します。 – alexfernandez

+0

私はまだエラーを見て、error_reporting(E_ALL)の出力を得るでしょうか? – spankmaster79

+1

@ spankmaster79はい、あなたの端末の標準エラーに行きます。デフォルトでは、ほとんどの端末は標準出力と標準エラーを一緒に出力しますが、実際は別々のストリームです。 –

3

ファイルの中に私がをテスト/含むのに$_SESSIONを使用するために、もっと根本的な解決策がありました。 私は"session_start();"コマンド「印刷$バッファ」を持っている../PHPUnit/Utils/Printer.phpPHPUnitののいずれかのファイルを編集しました。

それは私の魅力のように私のために働いた。しかし、私は "joonty"ユーザーのソリューションはこれまで最高のものだと思います。phpunit.xmlでprocessIsolation =「true」のオプションを設定する類似して

[email protected] [~/test]# phpunit --process-isolation HeadersTest.php 

+0

プルリクエストをリポジトリに提出しましたか?私はこれが共通の問題かもしれないと思います。 – t1gor

+0

私はphpunit bootstrap.phpでsession_start()を呼び出してくれました。 – bumperbox

-1

@runInSeparateProcessに対する代替解決策は、PHPUnitのを実行するとき--process分離オプションを指定することです。

このソリューションには、--stderrオプションを指定するのと同じ利点/短所がありますが、私の場合は機能しませんでした。別々のPHPプロセスで各テストを実行するためにパフォーマンスが低下する可能性はありますが、基本的にコードを変更する必要はありません。

+0

これは原因を特定していくつかのテストを行う最初のステップですが、保守可能なテストを作成するには直接埋め込みテストファイルへの注釈。コマンドラインから「特別な」オプションが少なくなると、CIシステム構成のメンテナンスが容易になります。 – Shi

4

私にとっては、headers_list()は0個の要素を返していました。私は質問に@titelのコメントに気づき、それがここで特別な言及に値する考え出し:私はそれをXML設定ファイルにprocessIsolationを定義するためのより良い解決策だと思うすでにコメントで述べた

Just wanted to cover this if there are some other people interested in this as well. headers_list() doesn't work while running PHPunit (which uses PHP CLI) but xdebug_get_headers() works instead.

HTH

0

として、 like

このように、--stderrオプションを渡す必要はありません。これは、あなたの同僚を苛立たせる可能性があります。

+1

それを必要とするテストのためだけに定義する方がよいでしょう。すべてのテスト用に設定すると、テストを遅くするだけです。 – Shi

関連する問題