Posted at

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

More than 1 year has passed since last update.

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 じゃもう普通にやってるよ、ってことで調べた内容でした。感謝!