やりたかったこと
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まで含めて、無事テストランができたのは、以下の組み合わせだった。
{
"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"
}
}
{
"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を自分で書いて指定しなければならないのかもしれませんが、今の時点ではよくわかりません。(不確かな記述でゴメンなさい。)
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を覗いてみると、(出力は整形してますが、)
"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",
"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の勉強を進める過程で、別のエラーが出たら、また力づくの対応をしようかと思っています。