PHPUnitを動かしたかったので、無理やり動かした。


# やりたかったこと
Macで、Zend Framework 2を使用。
PHPUnitをインストールして、テストの自動化に挑戦したい。
そのために、Zend Framework 2のチュートリアル
https://framework.zend.com/manual/2.4/en/tutorials/unittesting.html
を試すため、環境をセットアップしたい。
ただ、Seleniumとか、code-coverageなども使えるようにしたかったため、あれこれと、もがいた。

# 環境
Mac (OS X El Capitan / 10.11.6)
PHP 5.6.23 (cli) (built: Jun 26 2016 13:17:47) 
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend 
    with Zend OPcache v7.0.6-dev
    with Xdebug v2.2.5, 
Composer version 1.2.0 2016-07-19 01:28:52

## 実行環境
XAMPP 5.6.11-0 (MySQL, Apache)

# いくつか(かなり)の試行錯誤
最初、pearでのインストールを試したが、想定している設定ファイルと別のファイルに設定されているのか、何だか怒られっぱなし。
こんな感じ

```
WARNING!  The include_path defined in the currently used php.ini does not
contain the PEAR PHP directory you just specified:
```
XAMPPのphp.iniの設定とうまく整合しないのか、PEAR通の皆様、私の不勉強が悪いので、決してPEARが悪いわけではないと思いますが、断念。

次に
https://phpunit.de/manual/current/ja/installation.html
の手順に従って試すも、
>システム全体で使えるように Composer でインストールするには、次のようにします。
> `composer global require "phpunit/phpunit=5.5.*"`
> `~/.composer/vendor/bin/` にパスを通すことを忘れないようにしましょう。 

という、このあたりからphpunitでコマンドを叩いてもエラーが出るばかり。

# composerを使った
話が前後しますが、
http://qiita.com/CatCable/items/02364adacf36410f449e
この方は、brewを使われたらしいのですが・・・私は
https://getcomposer.org/download/
の手順に従って、composerをセットアップしました。

# PHPUnitのインストール

最終的には、
`composer global require "phpunit/phpunit=3.7.0"`
このコマンドでOK。（最終的には、3.7.0を指定し、それにもかかわらず、phpunitのコマンドに`PHPUnit 4.8.27 by Sebastian Bergmann and contributors.`という応答が返る、という不思議な現象が・・・）
ここで表示されるバージョン番号は`@package_version@`という変数から拾っているので、いつ、どこで入れてしまったのか確認する必要があるなと思いましたが、とりあえず先送り。（動けばいい式のアバウトさですが・・・すみません。）
ところが、

> Fatal error: require_once(): Failed opening required 'PHP/Timer/Autoload.php' (include_path='/Users/myName/.composer/vendor/phpunit/phpunit-mock-objects:...:/Users/myName/.composer/vendor/symfony/yaml:.:/usr/local/php5/lib/php') in /Users/myName/.composer/vendor/phpunit/phpunit/PHPUnit/Autoload.php on line 47

というエラーメッセージに遭遇。
この　~/.composer/vendor/phpunit/phpunit/PHPUnit/Autoload.phpに記された

```
require_once 'File/Iterator/Autoload.php';
require_once 'PHP/CodeCoverage/Autoload.php';
require_once 'PHP/Timer/Autoload.php';
require_once 'PHPUnit/Framework/MockObject/Autoload.php';
require_once 'Text/Template/Autoload.php';
```
の下4行で指定されたファイルが存在しない、と怒ってくる。
（あ〜、明らかに、私があれこれとバージョンを食い散らかしたから、そのせいなのか・・・）
いっその事、全部消して最初から、と思いつつ、Zend Framework2とのバージョンの整合なのか、phpunitの5.5とか、最新の安定版などだと、zendframeworkとの共存でエラーが出てくる。（composerがエラーを吐き出してくるため、どうやら、Zend Frameworkと組み合わせる限り、ネットで拾ってきた「最新版を入れる」やり方だと問題があって、噛み合うバージョンを指定しなければならない **らしい**。

（私の理解不足があるかも知れません。）
結局、バージョンをあれこれと変えながら、最終的にSeleniumまで含めて、無事テストランができたのは、以下の組み合わせだった。

```~/.composer/composer.json
{
    "require-dev": {
		"phpunit/phpunit": ">=3.7.0",
		"piece/stagehand-testrunner": "3.6.*",
		"phpunit/dbunit": ">=1.2",
		"phpunit/php-file-iterator": ">=1.3.1@stable",
		"phpunit/php-code-coverage": ">=1.2.0@stable",
		"phpunit/php-text-template": ">=1.1.1@stable",
		"phpunit/php-timer": ">=1.0.2@stable",
		"phpunit/php-token-stream": "1.4.8",
		"phpunit/phpunit-mock-objects": ">=1.2.0@stable",
		"mockery/mockery": "0.7.*"
    },
    "require": {
        "phpunit/phpunit-selenium": "1.4.2"
    }
}
```

```zend_project_root/composer.json
{
	"require": {
    	"php": ">=5.3.3",
    	"zendframework/zendframework": "2.3.3",
		"monolog/monolog": "1.0.*"
    },
    "require-dev": {
		"phpunit/phpunit": ">=3.7.0",
		"piece/stagehand-testrunner": "3.6.*",
		"phpunit/dbunit": ">=1.2",
		"phpunit/php-file-iterator": ">=1.3.1@stable",
		"phpunit/php-code-coverage": ">=1.2.0@stable",
		"phpunit/php-text-template": ">=1.1.1@stable",
		"phpunit/php-timer": ">=1.0.2@stable",
		"phpunit/php-token-stream": "1.4.8",
		"phpunit/phpunit-mock-objects": ">=1.2.0@stable",
		"phpunit/phpunit-selenium": ">=1.2",
		"mockery/mockery": "0.7.*"
    }
}
```

componentにこれらを指定した時点で、幾つかのファイルはAutoload.phpがインストールされたものの、指定されたpathとAutoloadの記述がかみ合わないものもあったため、require_onceをコメントアウトした。また、Text/Template/Autoload.phpについては、同じ機能が提供されている別フォルダのautoload.phpを指定し直した。

もしかしたら、完全にテストを実行するためには、幾つかのAutoload.phpを自分で書いて指定しなければならないのかもしれませんが、今の時点ではよくわかりません。（不確かな記述でゴメンなさい。）

``` Autoload.php
require_once 'File/Iterator/Autoload.php';
# require_once 'PHP/CodeCoverage/Autoload.php';
# require_once 'PHP/Timer/Autoload.php';
# require_once 'PHPUnit/Framework/MockObject/Autoload.php';
# require_once 'Text/Template/Autoload.php';
require_once 'tests/autoload.php';
```

手順としては、上記のcomposer.jsonを書き換えてから、
まず
`composer global require "phpunit/phpunit=3.7.0"`
を実行。次に
`composer global require "phpunit/phpunit-selenium=1.4.2"`
を実行。

seleniumも、require-dev"の方に移せるのでは？と思うが、今は触る元気がありません。

結果的に、
$ cat composer.lock | grep -e name -e version
で、composer.lockを覗いてみると、(出力は整形してますが、)

``` .composer/composer.lock
            "name": "phpunit/php-code-coverage",
            "version": "2.0.17",
            "name": "phpunit/php-file-iterator",
            "version": "1.3.4",
            "name": "phpunit/php-text-template",
            "version": "1.2.1",
            "name": "phpunit/php-timer",
            "version": "1.0.8",
            "name": "phpunit/php-token-stream",
            "version": "1.4.8",
            "name": "phpunit/phpunit",
            "version": "3.7.0",
            "name": "phpunit/phpunit-mock-objects",
            "version": "2.0.10",
            "name": "phpunit/phpunit-selenium",
            "version": "1.4.2",
            "name": "sebastian/comparator",
            "version": "1.1.0",
            "name": "sebastian/diff",
            "version": "1.4.1",
            "name": "sebastian/environment",
            "version": "1.3.7",
            "name": "sebastian/exporter",
            "version": "1.0.2",
            "name": "sebastian/version",
            "version": "1.0.6",
            "name": "symfony/yaml",
            "version": "v2.8.9",
            "name": "mockery/mockery",
            "version": "0.7.2",
            "name": "phpunit/dbunit",
            "version": "1.3.2",
            "name": "piece/stagehand-alterationmonitor",
            "version": "2.0.0",
            "name": "piece/stagehand-componentfactory",
            "version": "v1.0.1",
            "name": "piece/stagehand-testrunner",
            "version": "v3.6.2",
            "name": "symfony/class-loader",
            "version": "v3.1.3",
            "name": "symfony/config",
            "version": "v3.1.3",
            "name": "symfony/console",
            "version": "v3.1.3",
            "name": "symfony/dependency-injection",
            "version": "v3.1.3",
            "name": "symfony/filesystem",
            "version": "v3.1.3",
            "name": "symfony/finder",
            "version": "v3.1.3",
            "name": "symfony/polyfill-mbstring",
            "version": "v1.2.0",
            "name": "symfony/process",
            "version": "v3.1.3",
```

``` zend_project_root/composer.lock
            "name": "monolog/monolog",
            "version": "1.0.2",
            "name": "zendframework/zendframework",
            "version": "2.3.3",
            "name": "zendframework/zendxml",
            "version": "1.0.2",
            "name": "doctrine/instantiator",
            "version": "1.0.5",
            "name": "phpdocumentor/reflection-common",
            "version": "1.0",
            "name": "phpdocumentor/reflection-docblock",
            "version": "3.1.0",
            "name": "phpdocumentor/type-resolver",
            "version": "0.2",
            "name": "phpspec/prophecy",
            "version": "v1.6.1",
            "name": "phpunit/php-code-coverage",
            "version": "2.2.4",
            "name": "phpunit/php-file-iterator",
            "version": "1.4.1",
            "name": "phpunit/php-text-template",
            "version": "1.2.1",
            "name": "phpunit/php-timer",
            "version": "1.0.8",
            "name": "phpunit/php-token-stream",
            "version": "1.4.8",
            "name": "phpunit/phpunit",
            "version": "4.8.27",
            "name": "phpunit/phpunit-mock-objects",
            "version": "2.3.8",
            "name": "sebastian/comparator",
            "version": "1.2.0",
            "name": "sebastian/diff",
            "version": "1.4.1",
            "name": "sebastian/environment",
            "version": "1.3.7",
            "name": "sebastian/exporter",
            "version": "1.2.2",
            "name": "sebastian/global-state",
            "version": "1.1.1",
            "name": "sebastian/recursion-context",
            "version": "1.0.2",
            "name": "sebastian/version",
            "version": "1.0.6",
            "name": "symfony/yaml",
            "version": "v3.1.3",
            "name": "webmozart/assert",
            "version": "1.1.0",
```

本来は、この辺を全部自動でやってもらうためにcomposerがある、はずなんでしょうが、私の不勉強からか、無理やり設定した感があります。

泥沼の発端は、Autoload.phpの require_onceでファイルが見つからない、というエラーでした。ただ、テストを実行するために必要なモジュールをAutoloadするためのファイル、という位置付けのようなので、できることならば、コメントアウトせずに、必要なモジュールを追加する形で対応したかったです。
ただ、このファイル、Zend FrameworkのTutorialの手順に従った時点ですでに生成されていたので、私が悪いとばかりは言えないような気もします。

composerが自動生成してくれた ~/.composer/vendor/autoload.phpとの関連も、もう少し調べてみて、わかったら、またアップするかもしれません。

本当に、結果オーライなのかわかりませんが、もしTutorialの勉強を進める過程で、別のエラーが出たら、また力づくの対応をしようかと思っています。