PHP5.3 対応でも PHPUnit は 6 スタイルの記述へ移行しよう

  • 12
    いいね
  • 6
    コメント

PHPUnit は 6.0 で PHP7.0 未満との互換性を切り捨てました。それとともに、Zend1 式の名前空間を捨てて、PHP5.3 で導入された名前空間に移行しました。

<?php
use PHPUnit\Framework\TestCase;

class MyTestCase extends TestCase
{

}

PHPUnit >= 6.0 にはもう PHPUnit_Framework_TestCase はありません。use PHPUnit\Framework\TestCase; が今後のスタイルです。

でも、弊社まだ本番に 5.x がいるんですよ、とか、自分の公開しているライブラリ/フレームワークには 5.x 互換性の維持が必要で、とか、完全に 7 になりきれない事情がいろいろありますよね。高い方に合わせると前のやつが動かない、低い方に合わせておけばどうにか両バージョン動く、みたいな。

...て、それ、もういらない心配ですから!

すでに誰でも名前空間バージョンで書いていいようになってますから。
てか、アクティブにメンテしてるのに名前空間じゃないとか、今後取り残されますから。

証拠を先に出すとこうです。

composer.json
{
    "require": {
        "php": "^5.3.3 || ^7.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
    }
}

これが、phpunit/php-timersebastian/diff の現在の composer.json
です。PHP5.3 をサポートしつつも、ランタイムで許されたもののうち、可能なかぎり高いバージョンの PHPUnit を使うようにしている。

  • PHP > 7.0 : PHPUnit = ^6.0
  • PHP == 5.6.x : PHPUnit = ^5.7
  • PHP == 5.3.x 〜 5.5.x : PHPUnit = ^4.8.35

で、実際そのライブラリのテストコードが全部共通でこれ

phpunit/php-timer/tests/TimerTest.php
<?php
/*
 * This file is part of the PHP_Timer package.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use PHPUnit\Framework\TestCase;

class PHP_TimerTest extends TestCase
{

5.3.x サポートなのになんで!?

ここで PHPUnit の 4.8.35のソース5.7.0のソース を見てみましょう。

ForwardCompatibility とかいうフォルダがありますね。

<?php
/*
 * This file is part of PHPUnit.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace PHPUnit\Framework;

use PHPUnit_Framework_TestCase;

abstract class TestCase extends PHPUnit_Framework_TestCase
{
}

なるほどな〜

6.0 に下位互換性を入れなかったのは、将来を考えると良い判断だと思います。で、逆に、レガシー側に上位互換性を持たせた。~4.8.0 ってなってる人の環境にも、マイナーバージョン更新でいつの間にかインストールされてる、と。頭いいな。

これでみんなこの ForwardCompatibility が入ったバージョンまでは底上げされるやろ? ということみたいなので、composer update しておきましょう。(PHPUnit5 系にはすでに 5.5.0 の時点で ForwardCompatibility が入っていました。互換性のために可能な限り下げたい、ということなら、^5.5 でもいいかも)

PhpStorm も 2017.1 にちゃんと上げてあれば対応しますから : PHPUnit 6 and PhpStorm 2017.1 | PhpStorm Blog

あ、まあ、PHP は 5.6 未満はもう EOL なので、ほとんどの場合現実的にはこれが妥当じゃないかと思います。

composer.json
{
    "require": {
        "php": "^5.6 || ^7.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^5.7.20 || ^6.0"
    }
}

5.7.20 以上としたのは、5.7.12 以下のものにされちゃうと、うっかり PHPUnit x.x.x by Sebastian Bergmann ... のアレのバージョン表記を間違うバグがある (バグがあるバージョンの sebastian/version を使っている) ためです。

^5.7 だと Composerで低いバージョンの依存テスト - Qiita をやったとき、5.7.0 が選ばれてしまうんですが、それだと TravisCI のログに PHPUnit のバージョンじゃなくて、テスト対象のリポジトリのバージョンが表示されちゃう。

PHP7 + --prefer-lowest でも、どっちみち 5.7.x が選択される (レガシーだけど一応 >= 7.0 対応) ので、^6.0 の部分についてはそれほどデリケートにならなくていいと思います。


とかなんとか常識やでみたいに言うてますが、実はこれ、自分も最近ようやく知りました。Packagistを見ていてこういうのがちょいちょい出てきてて、

php: ^5.6 || ^7.0
phpunit/phpunit: ^6.0.8 || ^5.7.15

え、なんで?? ってなったので、 @slywalker 氏に聞いたら Cake3 じゃもう普通にやってるよ、ってことで調べた内容でした。感謝!