gruntでファイル変更を監視しながらFuelPHPのテストをPHPUnitで実行する


# 注意

- FuelPHPもgruntも勉強し始めたばかりのオレオレ流なので、真似て良いかどうかは疑って下さい
- TestCaseを継承したテストを実行する場合です
- PHPUnit_Framework_TestCase を継承するテストの場合は、 http://qiita.com/gigatune/items/e95936565c18e9e2e7ef の方が簡単です
- http://qiita.com/gigatune/items/e95936565c18e9e2e7ef のように、composer.pharでPHPUnit をインストールしているのが前提です


# 設定

| 項目 | 値 |
| ---  | --- |
| FuelPHP のプロジェクトpath | /path/to/project |
| gruntコマンドを実行するpath | /path/to/project |
| gruntの設定ファイル | /path/to/project/Gruntfile.js |
| TestCaseに渡すconfigファイル | /path/to/project/phpunit.xml |
| テスト対象のファイル | /path/to/project/fuel/app/tests/(controller|model|view)/*.php |


# テストファイルの作成

TestCase を継承したテストファイルを作成する。
実行例として、 /path/to/project/fuel/tests/controller/SampleTest.php というファイルを、以下の内容で作成。

```
<?php

class Test_Controller_ extends \TestCase
{
    protected function setUp()
        {
                parent::setUp();
        }

    protected function tearDown()
        {
                parent::tearDown();
        }

    public function test_index(){

                $this->assertTrue( true );
        }

}

```


# nodeモジュールのインストール

gruntコマンドを実行するpathに移動して、npmコマンドでインストール

```
$ cd /path/to/project
$ npm install --save-dev grunt grunt-phpunit grunt-contrib-watch
```

# phpunitに渡すconfigファイルの作成

/path/to/projct/phpunit.xml というファイルを、以下の内容で作成

```
<phpunit bootstrap="fuel/core/bootstrap_phpunit.php" colors="true" stoponfailure="false">
  <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>
  </testsuites>
</phpunit>
```

# テストがうまく通るかのテスト

```
$ cd /path/to/project/
$ ./fuel/vendor/bin/phpunit --configuration phpunit.xml ./fuel/app/tests 
PHPUnit 3.7.38 by Sebastian Bergmann.

Configuration read from /**/**/**/phpunit.xml

.

Time: 77 ms, Memory: 3.75Mb

OK (1 test, 1 assertion)
```

# gruntの設定ファイルを作成

/path/to/project/Gruntfile.js として、以下の内容で作成

```
module.exports = function( grunt ){
    grunt.initConfig({
        phpunit: {
            options: {
                bin : './fuel/vendor/bin/phpunit',
                configuration : './phpunit.xml',
                colors : true,
                followOptput: true
            },
            test: {
                dir : './fuel/app/tests/'
            }
        },
        watch: {
            php: {
                tasks: ['phpunit'],
                files: [
                    './fuel/app/tests/*/*.php'
                ]
            }
        }
    });

    grunt.loadNpmTasks( 'grunt-contrib-watch' );
    grunt.loadNpmTasks( 'grunt-phpunit' );

    grunt.registerTask( 'default', ['watch'] );
}
```
　
# gruntでテスト

```
$ cd /path/to/project
$ grunt watch
Running "watch" task
Waiting...
```

別ターミナルで、/path/to/project/fuel/tests/controller/SampleTest.php の ``` $this->assertTrue( true ); ``` を ```$this->assertTrue( false ); ``` に修正

```
$ grunt watch
Running "watch" task
Waiting...
>> File "fuel/app/tests/controller/QuizRestTest.php" changed.
Running "phpunit:test" (phpunit) task
Starting phpunit (target: test) in fuel/app/tests/
PHPUnit 3.7.38 by Sebastian Bergmann.

Configuration read from /path/to/project/phpunit.xml

F

Time: 88 ms, Memory: 3.75Mb

There was 1 failure:

1) Test_Controller_QuizAPI::test_index
Failed asserting that false is true.

/path/to/projct/fuel/app/tests/controller/SampleTest.php:23

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
Fatal error: Command failed: /bin/sh -c fuel/vendor/bin/phpunit --colors --configuration ./phpunit.xml fuel/app/tests/

Completed in 0.865s at Tue Nov 03 2015 19:01:31 GMT+0900 (JST) - Waiting...
```