Laravelプロジェクトの基本パッケージを試験対象外にする話
Laravelの基本パッケージって試験をやらないですよね。
でも、試験対象になっていてカバレッジ率が下がるのがめんどくさくないですか?
そもそもロジックもないのに試験対象に含まれているのでカバレッジ率がさがります、訳で…
チームで大体70%以上にしましょう!と言っても基本パッケージも含められると結構大変です。
今回はPHPUnitでの決められたクラス・ディレクトリを試験対象外にする方法をメモっておきます。
ちなみに、Laravelでプロジェクト新規作成直後試験を実行してみるとカバーしていないとなっています。
CUI
Summary:
Classes: 0.00% (0/9)
Methods: 0.00% (0/10)
Lines: 0.00% (0/24)
App\Console\Kernel
Methods: 0.00% ( 0/ 1) Lines: 0.00% ( 0/ 2)
App\Exceptions\Handler
Methods: 0.00% ( 0/ 1) Lines: 0.00% ( 0/ 1)
App\Http\Controllers\Controller
Methods: ( 0/ 0) Lines: ( 0/ 0)
App\Http\Kernel
Methods: ( 0/ 0) Lines: ( 0/ 0)
... 略
HTTPレポート

試験を実行する方法とは
忘れそうなのでPHPUnit試験の実行方法をメモっておきます
今回はphpdbgを使って楽々にしています
HTMLカバレッジレポート付き
coverageディレクトリ下にHTMLファイルが出来上がるので行単位のカバレッジが分かりやすいです
$ phpdbg -qrr vendor/bin/phpunit -c phpunit.xml --log-junit report.xml --verbose --coverage-html coverage/ --coverage-text
HTMLレポートなし
$ phpdbg -qrr vendor/bin/phpunit -c phpunit.xml --verbose --coverage-text
試験対象外を設定しまう
phpunitの設定はphpunit.xmlにあるのでそれをいじります
coverageがテストに関する部分です。
includeはテスト対象を
excludeはテスト対象外をそれぞれ指定します
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
<exclude>
<file >./app/Exceptions/Handler.php</file>
<file >./app/Http/Controllers/Controller.php</file>
<directory suffix=".php">./app/Http</directory>
<directory suffix=".php">./app/Providers</directory>
<directory suffix=".php">./app/Console</directory>
</exclude>
</coverage>
それだけです!
コミット的にはこんな感じ…
coverage範囲が対象です。下のserverがenvなのは無視してください
個人的嗜好
入れ物は試験対象外にする
個人的に以下の無視を追加しています
・ Classesはただの入れ物クラス
・ ModelはORMのDB周りのクラス
このクラス群にはロジックは絶対に入れません!
入れそうな誘惑は無理矢理にでも別にします
なのでこいつも追加します
<directory suffix=".php">./app/Classes</directory>
<directory suffix=".php">./app/Models</directory>
Controllerも試験対象外にする
え?App/Httpってアクセスコントローラも!と思う超洞察力の鋭いひとに向けてですが
私はControllerにはロジックは入れません!
<directory suffix=".php">./app/Http</directory>
・HTTPリクエストを解釈して、内部のリクエストへと変換する (もちろん別クラスで行うので呼び出しだけ)
・ 内部サービスに引き継ぐ
・ 結果を入れて返却する
こんな感じ
public function save(Request $req): JsonResponse
{
// リクエストを解析します
$saveRequest = BookRequestResponseUtil::convertSaveRequest($req);
Log::info("api/book/save " . $saveRequest);
// 保存処理に引き継ぎ
$saveResponse = $this->serviceController->save($saveRequest);
Log::info("api/book/save response " . $saveResponse);
// 結果を返却
return response()->json($saveResponse);
}
ねっ、BookRequestResponseUtilにて処理をまとめているのでUnit試験も楽ちんです。
HTTP Requestをまとめているので参照時の注意も集中できます
Futures試験でも通るかなとは思いますが…
終いに
自分の関与できる範囲が絞り込めるので試験がわかりやすくなりました!
ジョブ一覧にカバレッジ率を表示させるとやる気も出ますしw

目指せ!カバー率95%以上!
やりすぎたプロジェクトw
