初めに
PHPStanでは独自のカスタムルールを作成できるということをこちらの記事で解説しました。今回は作成したカスタムルールのユニットテストを作成してみようと思います。
(前提)PHPStanはPHPUnitを用いてUnitTestを書くことができる
PHPStanではユニットテストにPHPUnitが採用されています。各ルールはRuleTestCase
というクラスを継承してテストケースが作成されており、カスタムクラスでも同様にこのクラスを継承して作成します。
以下はRuleTestCase
の一部抜粋です。(全部で見たい方はこちらからどうぞ)
RuleTestCaseクラス
/**
* @api
* @template TRule of Rule
*/
abstract class RuleTestCase extends PHPStanTestCase
{
/**
* @return TRule
*/
abstract protected function getRule(): Rule;
/**
* @param string[] $files
* @param list<array{0: string, 1: int, 2?: string|null}> $expectedErrors
*/
public function analyse(array $files, array $expectedErrors): void
{
// テストケースを実行する処理が書いてある
// 見づらくなるため割愛
}
}
ポイント
- getRule()メソッド
- テストしたいルールクラス指定する
- analyse()メソッド
- 実際に検証を行うメソッド
- 引数で以下の情報をもらい、getRule()で指定したルールを検証する
- 検証対象のファイルのパス
- 期待値(出力されてほしいエラー)
UnitTest作成方法
ということで、実際に実装してみます。
今回は以下のようなカスタムルールを用意しました。このテストケースを作成してみます。
MethodNameRule
class MethodNameRule implements Rule
{
public function getNodeType(): string
{
return Node\Stmt\ClassMethod::class;
}
/**
* @param Node\Stmt\ClassMethod $node
* @param Scope $scope
* @return string[]
*/
public function processNode(Node $node, Scope $scope): array
{
$methodName = $node->name->toString();
// 'get' または 'post' で始まっているかをチェック
if (!preg_match('/^(get|post)/', $methodName)) {
return [sprintf(
'メソッドの名前はgetかpostで始めてください!)];
}
return [];
}
}
実際に作成するのは以下の二種類です。
- RuleTestCaseを継承した、テストケースを記載するファイル
- 検証用のPHPファイル
まずは検証用のPHPファイルを用意しました。
TestObject
<?php
namespace Path\to\Project\test\data;
class TestObject
{
/**
* get始まりなのでOK
*/
public function getTest() {}
/**
* post始まりなのでOK
*/
public function postTest(){}
/**
* 始まりがgetでもpostでもないので始まりなのでNG
*/
public function fetchTest(){}
}
続いて、RuleTestCaseを継承してUnitTestを作成します。
<?php
namespace Path\to\Project\test\;
use PHPStan\Testing\RuleTestCase;
use Path\to\Project\rule\MethodNameRule;
class MethodNameRuleTest extends RuleTestCase
{
protected function getRule(): \PHPStan\Rules\Rule
{
// ポイント1: 今回テストしたいルールを指定
return new MethodNameRule();
}
/**
* ポイント2: PHPUnitのルールでテストケースを記載
*/
public function test_メソッド名はpostかgetから始まってないといけない(): void
{
// ポイント3: analyseメソッドを用いてテストを定義
$this->analyse(
[__DIR__ . '/data/Hoge.php'],
[
['メソッドの名前はgetかpostで始めてください!', 19] // 期待値と行数
]
);
}
}
実行はPHPUnitのコマンドでOKです。
無事に実行できました!
> vendor/bin/phpunit .\src\test
PHPUnit 11.5.2 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.17
. 1 / 1 (100%)
Time: 00:00.588, Memory: 36.00 MB
OK (1 test, 1 assertion)
終わりに
今回はPHPStanのカスタムルールのテストケースを作成しました。
サクッとかけて簡単なので、書いてみてはいかがでしょうか。
ここまでご覧いただきありがとうございました!