PHPUnit を自作した
PHP の勉強ついでに、PHPUnit のコードを読んで、それを実装してみました。成果物は主に下のファイル。
PHPUnit とは
PHPUnit と言えば、PHP のテストではみんなが使っていると言われているライブラリーです。
最新版のバージョンは 10 になっていて( dev バージョンなので、一番使われている最新版は 9.5 や 8 などになると思います)、10 と 8 や 9 は内部の関数の仕様が変わっていたりしています(run
の返り値が TestResult
から void
に変わるなど... )。
PHPUnit の使い方
などを見れば、PHPUnit10 の使い方が書いてありますが、Composer で簡単に使い方を説明すると、
<?php
require 'vendor/autoload.php';
use PHPUnit\Framework\TestCase;
class CounterTest extends TestCase {
public function testCounter() {
$counter = 1;
$this->assertSame($counter, 1, "This should be equal.");
}
}
のようなファイルを書いて、
./vendor/bin/phpunit ./tests
を実行すれば、テストを実行できます。
ミニ PHPUnit の解説
PHPUnit を読んでみると、PHPUnit 自体は全て理解しようとして読むのはタフで大変ですが、簡単に実装するだけなら簡単です。実際読んでみれば、PHPUnit の基本の「キ」くらいは分かるのではないでしょうか?
一応ソースコードの解説をします。
全体像を説明すると、
- MyPHPUnit を継承したクラスと MYPHPUnit自体 からメソッドを全取得。
- メソッド名から、テストのメソッド・テスト前に実行するメソッド・テスト後に実行するメソッド を分ける。
- 分けたメソッドを順番通りに実装し、テストメソッドでは結果を集計する。
- 結果を取得する。
では、コードを読んでみましょう。
メソッドの全取得
まず、メソッドの全取得を行なっているのが、ここの、
$current_class = new ReflectionClass($this);
$class_methods = $current_class->getMethods();
になります。継承しただけで、親の方から子のメソッドにアクセスできるなんて、PHP は簡単にできていますね。
メソッドの分別
次に、上で取得した $class_methods を Test配列・Before配列・After配列に分別します。
foreach ($class_methods as $class_method) {
$class_method_name = $class_method->name;
if (str_starts_with($class_method_name, "test")) {
array_push($test_methods, $class_method_name);
} elseif (str_starts_with($class_method_name, "before")) {
array_push($before_methods, $class_method_name);
} elseif (str_starts_with($class_method_name, "after")) {
array_push($after_methods, $class_method_name);
}
}
テスト・Before・After を順番に実行
内容は簡単ですが、run で テストを実行しているのがわかると思います。
原本のコードだと、ここ らへんになります。
foreach ($before_methods as $before_method) {
$this->{$before_method}();
}
foreach ($test_methods as $test_method) {
$this->setName($test_method);
$this->run();
}
foreach ($after_methods as $after_method) {
$this->{$after_method}();
}
結果の取得
最後に結果を MyPHPUnit->getResult()
から取得します。
コードを読んでみると、中身は結構簡単に見えると思います。
最後に
ここまでコードを辿れば、PHPUnit のやっていることが、分かったのではないでしょうか?
簡単な実装だけなら、結構簡単でしたね。
中身のもっと難しい実装に興味を持ってもらって、PHPUnit の気持ちになって開発ができる一助になれれば幸いです。