Stagehand_Testrunner で Session エラー が出た

セッションを絡んだ箇所のテストコードを PHPUnit で書いていると

Zend_Session_Exception: Session must be started before any output has been sent to the browser; output started in /usr/local/lib/php/PHPUnit/Util/Printer.php/174

というつれないエラーが出た。

id:shimooka さんの所に PHPUnit で header already sent 〜に対処するパッチがあるので、それを当てて PHPUnit を実行するとうまい事動いた。
http://d.hatena.ne.jp/shimooka/20090811/1249983652
id:shimooka ++


が、Piece Framework の Stagehand_Testrunner を使用してテストコードを実行すると依然エラーが出る。
以下再現コード。
# Zend_Auth を使用しているので、include_path に Zend Framework を設置。

<?php
class Hoge
{
    public function __construct()
    {
    }
    public function auth()
    {
        $data = new StdClass;
        $data->name = 'hoge';
        $data->mail = 'example@example.com';
        $auth = Zend_Auth::getInstance();
        $auth->getStorage()->write($data);
        return true;
    }
}

prepare.php

<?php
$root = dirname(dirname(__FILE__));
$lib  = dirname(dirname(__FILE__)) . '/library';
$app  = dirname(dirname(__FILE__)) . '/app';

set_include_path(get_include_path() . PATH_SEPARATOR .
                 $root . PATH_SEPARATOR .
                 $lib . PATH_SEPARATOR .
                 $app . PATH_SEPARATOR
);

require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
require_once 'PHPUnit/Framework.php';

テストコード

<?php
require_once 'prepare.php';
class HogeTest extends PHPUnit_Framework_TestCase
{
    public function testAuth()
    {
        $hoge = new Hoge();
        $ret  = $hoge->auth();
        $this->assertTrue($ret);
    }
}

これを実行すると、以下のようなつれないエラーが…。

testrunner HogeTest.php
PHPUnit 3.3.17 by Sebastian Bergmann.

E

Time: 0 seconds

Hoge
 - Auth

There was 1 error:

1) testAuth(HogeTest)
Zend_Session_Exception: Session must be started before any output has been sent to the browser; output started in /usr/local/lib/php/PHPUnit/Util/Printer.php/174
/var/www/localhost/library/Zend/Session.php:453
/var/www/localhost/library/Zend/Session/Namespace.php:143
/var/www/localhost/library/Zend/Auth/Storage/Session.php:87
/var/www/localhost/library/Zend/Auth.php:91
/var/www/localhost/app/Hoge.php:13
/var/www/localhost/tests/HogeTest.php:8
/usr/local/lib/php/src/Stagehand/TestRunner/Runner/PHPUnit.php:123
/usr/local/lib/php/src/Stagehand/TestRunner.php:389
/usr/local/lib/php/src/Stagehand/TestRunner.php:116
/usr/local/lib/php/bin/testrunner:44

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

原因は PHPUnit と同じで、Stagehand/TestRunner/Runner/PHPUnit.php で null を STDERR にすると解消された。
以下パッチ

*** /usr/local/lib/php/src/Stagehand/TestRunner/Runner/PHPUnit.php>2009-08-18 22:34:00.000000000 +0900
--- PHPUnit.php>2009-08-18 22:48:20.000000000 +0900
***************
*** 99,117 ****
      public function run($suite, $config)
      {
          $printer =
!             new Stagehand_TestRunner_Runner_PHPUnit_Printer_Result(null,
                                                                     false,
                                                                     $config->color
                                                                     );

          $listeners = array(new Stagehand_TestRunner_Runner_PHPUnit_Printer_TestDox('testdox://', $config->color));
          if (!$config->isVerbose) {
!             $listeners[] = new Stagehand_TestRunner_Runner_PHPUnit_Printer_Progress(null,
                                                                                      false,
                                                                                      $config->color
                                                                                      );
          } else {
!             $listeners[] = new Stagehand_TestRunner_Runner_PHPUnit_Printer_DetailedProgress(null,
                                                                                              false,
                                                                                              $config->color
                                                                                              );
                                                                                              );
--- 99,117 ----
      public function run($suite, $config)
      {
          $printer =
!             new Stagehand_TestRunner_Runner_PHPUnit_Printer_Result(STDERR,
                                                                     false,
                                                                     $config->color
                                                                     );

          $listeners = array(new Stagehand_TestRunner_Runner_PHPUnit_Printer_TestDox('testdox://', $config->color));
          if (!$config->isVerbose) {
!             $listeners[] = new Stagehand_TestRunner_Runner_PHPUnit_Printer_Progress(STDERR,
                                                                                      false,
                                                                                      $config->color
                                                                                      );
          } else {
!             $listeners[] = new Stagehand_TestRunner_Runner_PHPUnit_Printer_DetailedProgress(STDERR,
                                                                                              false,
                                                                                              $config->color
                                                                                              );

ってここまで書いておいて header already 云々なので先頭でセッションを開始すればいけるんとちゃう?と思ったので、やってみたら行けた。

<?php
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
Zend_Session::start(true);
require_once 'PHPUnit/Framework.php';
testrunner -c HogeTest.php
PHPUnit 3.3.17 by Sebastian Bergmann.

.

Time: 0 seconds

Hoge
 - Auth

OK (1 test, 1 assertion)

これって Stagehand_Testrunner の不具合か?って言われると凄く微妙な気がする。
でもまぁ一応報告しとくかと思ったけど、どこに報告すりゃええのかよく分からんかった。