複数回に分けて実行した PHPUnit のコードガバレッジを phpcov でマージする

次のようなディレクトリ構成だとします。

```
src/
  A/
    Hoge.php
  B/
    Fuga.php
tests/
  A/
    HogeTest.php
  B/
    FugaTest.php
bootstrap.php
composer.json
phpunit.xml.dist
merge-coverage.php
```

merge-coverage.php の内容は後述します、その他のファイルはよくある普通の内容です。

テストを複数回に分けて実行します。このとき、phpunit のオプションで `--coverage-php` を指定します。

```console
$ rm -fr build/coverage
$ mkdir -p build/coverage
$ vendor/bin/phpunit --coverage-php build/coverage/A.txt tests/A
$ vendor/bin/phpunit --coverage-php build/coverage/B.txt tests/B
```

build/coverage/ ディレクトリに PHP_CodeCoverage のインスタンスがシリアライズされたものが出力されます。

merge-coverage.php で `--coverage-php` の出力をマージして HTML レポートを出力します。

```console
$ php merge-coverage.php
$ open build/html/index.html
```

merge-coverage.php の内容は次の通りです。

```php:merge-coverage.php
<?php
require __DIR__ . '/bootstrap.php';

$list = glob(__DIR__ . '/build/coverage/*.txt');

/* @var $coverage PHP_CodeCoverage */
$coverage = null;

foreach ($list as $fn)
{
    $c = unserialize(file_get_contents($fn));

    if ($coverage === null)
    {
        $coverage = $c;
    }
    else
    {
        $coverage->merge($c);
    }
}

if ($coverage === null)
{
    $coverage = new PHP_CodeCoverage();
}

$report = new PHP_CodeCoverage_Report_HTML();
$report->process($coverage, __DIR__ . '/build/html');
```

---

なんてことをしなくても phpcov を使えば簡単にマージできます。

 - https://github.com/sebastianbergmann/phpcov

phpcov.phar をダウンロードします。

```console
$ wget https://phar.phpunit.de/phpcov.phar
$ php phpcov.phar --help
phpcov 1.1.0 by Sebastian Bergmann.

Usage: phpcov [switches] <file>
       phpcov --merge [switches] <directory>

  --clover <file>         Generate code coverage report in Clover XML format.
  --html <dir>            Generate code coverage report in HTML format.
  --php <file>            Serialize PHP_CodeCoverage object to file.
  --text <file>           Generate code coverage report in text format.

  --blacklist <dir|file>  Adds <dir|file> to the blacklist.
  --whitelist <dir|file>  Adds <dir|file> to the whitelist.

  --add-uncovered         Add whitelisted files that are not covered.
  --process-uncovered     Process whitelisted files that are not covered.

  --merge                 Merges PHP_CodeCoverage objects stored in .cov files.

  --configuration         Read configuration from XML file.

  --help                  Prints this usage information.
  --version               Prints the version and exits.
```

テストを分割して実行します。`--coverage-php` で指定する出力ファイルの拡張子は `*.cov` である必要があります。

```console
$ rm -fr build/coverage
$ mkdir -p build/coverage
$ vendor/bin/phpunit --coverage-php build/coverage/A.cov tests/A
$ vendor/bin/phpunit --coverage-php build/coverage/B.cov tests/B
```

phpcov でコードカバレッジをマージして HTML レポートを出力します。

`--html` で HTML レポートの出力先を、最後の引数 `build/coverage` で `*.cov` を保存したディレクトリを指定します。

```console
$ php phpcov.phar --merge --html build/html build/coverage
```

`--configuration` で phpunit.xml を指定すれば `<filter>` などの設定を利かすことができます。

```console
$ php phpcov.phar --merge --configuration phpunit.xml.dist --html build/html build/coverage
```

HTML 以外の形式も指定できるので clover などを一緒に出力することもできます。

```console
$ php phpcov.phar --merge --configuration phpunit.xml.dist --html build/html --clover build/clover.xml build/coverage
```