blog.petitviolet.net

PHPのTestでheader関数によるエラーを回避する

2014-07-17

QiitaPHP

まとめ

header関数を使っている関数などをテストする際には、テストを走らせる前に ob_start()と書きましょう

問題

PHP でテストしようとして、何故かSimpleTest - Unit Testing for PHPを利用した

テストを実行するとheader()によるエラーが出た

E_WARNING: Cannot modify header information - headers already sent by (output started at …

よくある感じのエラーで、header 関数によって header を設定しているが、その前にすでにechoprint_rなどで標準出力されている場合に出力されるエラーです テストモジュール自体が標準出力しているために、テストしたい場所でheader()を読んでも時既に遅し、的な感じ

なお、SimpleTest 以外で同様のエラーが出るかどうかは知らない

エラーの出るテストコード例

test.php
<?php
mb_internal_encoding('UTF-8');

require_once('simpletest/unit_tester.php');
require_once('simpletest/reporter.php');

class TestParameter extends UnitTestCase {
  public function __construct() {
  }

  public function testVar() {
    header("Content-Type: text/xml; charset=utf-8");
    $this->assertEqual("1", "1");
  }
}
$test = new TestParameter();
$test -> run(new TextReporter());

?>

これを走らすと…

$ php test.php
TestParameter
E_WARNING: Cannot modify header information - headers already sent by (output started at {PATH}/simpletest/repoter.php) in {PATH}/test.php on line 12
Exception 1!
Unexpected PHP error [Cannot modify header information - headers already sent by (output started at {PATH}/simpletest/reporter.php:213)] severity [2] in [{PATH}/test.php line 12]
        in testVar
FAILURES!!!
Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 1

というエラーが出てしまう

エラーの出ないテストコード例

まとめにも書いたように、テストの前にob_start()と書けばよい

test.php
<?php
mb_internal_encoding('UTF-8');

require_once('simpletest/unit_tester.php');
require_once('simpletest/reporter.php');

class TestParameter extends UnitTestCase {
  public function __construct() {
  }

  public function testVar() {
    header("Content-Type: text/xml; charset=utf-8");
    $this->assertEqual("1", "1");
  }
}
ob_start();  // これ
$test = new TestParameter();
$test -> run(new TextReporter());

?>

これで

$ php test.php
TestParameter
OK
Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0

となって一安心

ob_start()は標準出力自体を取得するための準備であるため、これを呼んでおくと標準出力が内部のバッファに保存されて、header()と干渉しなくなったと思われる

from: https://qiita.com/petitviolet/items/96e64f709f0ef7dcf612