FuelPHPにPHPUnitを導入したが、エラーが発生してテストできない

FuelPHPにPHPUnitを導入しても素直に実行できなかったため、解決策を書いておきます。

カーネルのバージョン

```
$ uname -a
Linux mp.startup-plus.jp 4.4.41-35.53.amzn1.x86_64 #1 SMP Mon Jan 9 23:00:57 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
```

OSのバージョン

```
$ head /etc/system-release
Amazon Linux AMI release 2016.09
```

PHPのバージョン

```
$ php --version
PHP 7.0.14 (cli) (built: Jan 18 2017 19:13:23) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
```

Composerのバージョン

```
$ php composer.phar --version
Composer version 1.3.1 2017-01-07 18:08:51
```

## PHPUnitのインストール

[PHPUnit マニュアル – 第1章 PHPUnit のインストール](https://phpunit.de/manual/current/ja/installation.html)のComposerを参考にインストールします。

```
$ ./composer.phar require --dev phpunit/phpunit ^6.1
```

## FuelPHPにPHPUnitを認識させる

Composerでインストールした場合、FuelPHPのインストールパスを認識させる必要があります。

まず設定ファイルを生成しましょう。

```
$ php oil g config oil
Created config: APPPATH/config/oil.php
```

設定ファイルを編集します。

```php:oil.php
<?php

return array(
	'phpunit' => 
	array(
		//'autoload_path' => 'PHPUnit/Autoload.php',
		'binary_path' => 'phpunit',
	),
);

/* End of file oil.php */
```

binary_pathを`VENDORPATH . 'bin/phpunit'`に変更し、autoload_pathを削除(コメントアウト)しました。

### エラー発生

いざ実行してみたところ、

```
Uncaught exception Oil\Exception: PHPUnit does not appear to be installed.

	Please visit http://phpunit.de and install.
Callstack: 
#0 /home/username/www/oil(68): Oil\Command::init(Array)
#1 {main}
```

というエラーが出ます。
[MAMP/php7/fuelphp1.8/PHPUnitでテストができる状況まで持っていくのが大変だった話 - Qiita](http://qiita.com/t-katsura/items/fac219d567444c8e99e2)によれば最新のPHPUnitに対応していないそうです。

### 解消

app/bootstrap.phpとapp/config/oil.phpを編集します。
bootstrap.phpには下記のコードを最下部にでも追加してください。oil.phpは設定を変更します。

```bootstrap.php
class PHPUnit_Framework_TestCase extends \PHPUnit\Framework\TestCase{}
```

```oil.php
<?php

return array(
	'phpunit' => 
	array(
		'autoload_path' => VENDORPATH . 'autoload.php',
		'binary_path' => VENDORPATH . 'bin/phpunit',
	),
);

/* End of file oil.php */
```

他にはpackages/oil/classes/command.phpの`"PHPUnit_Framework_TestCase"`を`"PHPUnit\\Framework\\TestCase"`に変更する方法もあります。
当初はこっちの方法でやる予定でしたが、Coreに手を入れるのはよろしくないと思い、他の方法を模索した結果bootstrap.phpに手を加えることにしました。

## 動作確認

いざ実行。

```
$ php oil t
Tests Running...This may take a few moments.
PHPUnit 6.2.2 by Sebastian Bergmann and contributors.

...............................................................  63 / 402 ( 15%)
......................RRRRRRRRRRRRRRRRRR...RRRRRRRRRRRRRRRRRRR. 126 / 402 ( 31%)
.............RR...RRRRRR......FRRRRRR..........FFFF............ 189 / 402 ( 47%)
.....RRR..F....RRRR........................................R... 252 / 402 ( 62%)
.RRR............E................F..RRRR....R................RR 315 / 402 ( 78%)
RRRRRR...................RRR................................... 378 / 402 ( 94%)
....................RRRR                                        402 / 402 (100%)

Time: 428 ms, Memory: 14.00MB

(中略)

ERRORS!
Tests: 402, Assertions: 494, Errors: 1, Failures: 7, Risky: 82.
```

実行結果が大量に出力されるので、中略しています。

## テストランナーの設定

core/phpunit.xmlがテストランナーの設定になります。
設定を変更したい場合は、app/phpunit.xmlにコピーし、それを変更しましょう。

```phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>

<phpunit colors="true" stopOnFailure="false" bootstrap="../core/bootstrap_phpunit.php">
	<php>
		<server name="doc_root" value="../../"/>
		<server name="app_path" value="fuel/app"/>
		<server name="core_path" value="fuel/core"/>
		<server name="package_path" value="fuel/packages"/>
		<server name="vendor_path" value="fuel/vendor"/>
		<server name="FUEL_ENV" value="test"/>
	</php>
	<testsuites>
		<testsuite name="core">
			<directory suffix=".php">../core/tests</directory>
		</testsuite>
		<testsuite name="packages">
			<directory suffix=".php">../packages/*/tests</directory>
		</testsuite>
		<testsuite name="app">
			<directory suffix=".php">../app/tests</directory>
		</testsuite>
		<testsuite name="modules">
			<directory suffix=".php">../app/modules/*/tests</directory>
		</testsuite>
	</testsuites>
</phpunit>
```

標準の設定ではテストスイートの名前がすでに設定されています。
そのため、Coreのテストを実行したくない場合はテスト実行時のオプションに`--testsuite=app`などをつけると良いでしょう。
使用できるコマンドラインオプションはFuelPHPドキュメントのOilパッケージに記述してあります。
テストを作成せずにappスイートを実行した場合、以下のようになります。

```
$ php oil t --testsuite=app
Tests Running...This may take a few moments.
PHPUnit 6.2.2 by Sebastian Bergmann and contributors.



Time: 25 ms, Memory: 4.00MB

No tests executed!
```

## テストを書く

[fuelPHPでPHPUnitを使ったユニット・コントローラーテストをするには - Qiita](http://qiita.com/masahikoofjoyto/items/206e6f8d5b0aa7126678)などを参考にどうぞ。