Dockerを使い手軽にPHPUnitをはじめる

# はじめに

これからPHPUnitを試す方の参考にもなるよう手順をまとめます。
といっても筆者も経験多くはないのであしからず。

# 環境

## Dockerを使って環境セットアップ

手っ取り早くPHPUnitを試してみたいという方も多いと思うので今回はDockerで環境を用意。
(なおDocker自体のインストールは割愛してます。)

```
$ docker pull php:5.6-apache
$ docker run -p 80:80 -v /(ホストの任意のパス)/:/var/www/html --name php56 -d php:5.6-apache
$ docker exec -ti php56 bash
```

これでDocker Hubからpullしたイメージで作成したdockerコンテナにログインした状態になります。
パッケージを最新の状態にし、composerを使える状態にしていきます。

```
$ apt-get update
$ apt-get install git vim
$ curl -sS https://getcomposer.org/installer | php
```

これでPHPはセットアップされ、composerも使える状態になったため、以降PHPUnitを追加する作業をはじめていきます。

## composerでPHPUnitインストール

composer.jsonは以下の通りです。
(PHPUnitは5.7系を利用)

```
{
    "name": "phpunit",
    "description": "PHPUnit",
    "require": {
        "phpunit/phpunit": "5.7.*"
    },
    "config": {
        "bin-dir": "/usr/local/bin/"
    }
}
```

composer.jsonが用意できたらPHPUnitインストールします。

```
$ ./composer.pha install
```

## 環境チェック

以上でPHPは5.6系、PHPUnitは5.7系が用意されています。
念のため確認をします。

```
$ php -v
PHP 5.6.31 (cli) (built: Jul 13 2017 18:38:40) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

$ phpunit --v
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.
```

# PHPUnitではじめてのテスト

環境の準備が完了したため、実際にPHPUnitを使ってみます。

## テストコード

firstTest.phpとしてファイルを用意します。
(今回はcomposerをセットアップしたディレクトリと同じ場所で作業しています)

```php
<?php
// 2017/07/31 tadsanさんにコメント頂き修正(test/bootstrap.phpへ移した)
// require_once 'vendor/autoload.php';

class firstTest extends PHPUnit_Framework_TestCase
{
    public function testMinimumViableTest()
    {
        $this->assertTrue(false, "falseはtrueではない");
    }
}
```

tests/bootstrap.phpとして以下ファイル作成。
(後述のphpunit.xml内にてbootstrap="tests/bootstrap.php"として読み込む。)

```php
<?php

require_once __DIR__ . '/../vendor/autoload.php';
```

## PHPUnitの設定
PHPUnitの設定ファイルです。
こちらもcomposerをセットアップした同じディレクトリ内に配置しています。
詳細な設定は把握しきれてないですがひとまずtestsuiteタグでは上記firstTest.phpのパスを指定していますのでそちらはチェックしておくといいでしょう。

```xml
<phpunit>
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
        backupGlobals="true"
        backupStaticAttributes="false"
        bootstrap="tests/bootstrap.php"<!-- 2017/07/31 tadsanさんにコメント頂き修正 -->
        cacheTokens="false"
        colors="false"
        convertErrorsToExceptions="true"
        convertNoticesToExceptions="true"
        convertWarningsToExceptions="true"
        forceCoversAnnotation="false"
        mapTestClassNameToCoveredClassName="false"
        printerClass="PHPUnit_TextUI_ResultPrinter"
        <!--printerFile="/path/to/ResultPrinter.php"-->
        processIsolation="false"
        stopOnError="false"
        stopOnFailure="false"
        stopOnIncomplete="false"
        stopOnSkipped="false"
        stopOnRisky="false"
        testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
        <!--testSuiteLoaderFile="/path/to/StandardTestSuiteLoader.php"-->
        timeoutForSmallTests="1"
        timeoutForMediumTests="10"
        timeoutForLargeTests="60"
        verbose="false">
        <testsuites>
          <testsuite name="My Test Suite">
            <file>./firstTest.php</file>
          </testsuite>
        </testsuites>
</phpunit>
```
## PHPUnitの実行
PHPUnitを実行してみると以下のように表示されます。
assertTrueメソッドにてステータスをfalseとして指定していますのでfailedとなっています。

```
$ phpunit -c phpunit.xml
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 348 ms, Memory: 3.00MB

There was 1 failure:

1) firstTest::testMinimumViableTest
falseはtrueではない
Failed asserting that false is true.

/var/www/html/firstTest.php:9

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
```

# 参考サイト
- Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築
(http://qiita.com/naga3/items/be1a062075db9339762d)
- PHPUnitとPHPのバージョン対応表(https://blog.shimabox.net/2016/09/15/phpunit-php-support-version/)
- XML 設定ファイル(https://phpunit.de/manual/current/ja/appendixes.configuration.html)
- 短気なプログラマのためのPHPUnitクックブック(https://leanpub.com/grumpy-phpunit-jp)