この記事は、「BASE Advent Calendar 2018」の13日目の記事です。
Backend Engineerの沖中 (@okinaka) です。
読者のみなさんはテストを書いてますか?テストが面倒くさいとか思ってませんか?(私はたまにあります)
そんな時、モチベーションをあげるには、どのような工夫をしていますか?
私の場合、カバレッジ計測の結果のレポートがとても役に立っています。 レポートを眺めると、視覚的に
- 「どの行が実行された」とか
- 「カバレッジ率が◯%」だとか
- 「ここ複雑だけどテストがないクラスがあるよ」など、
いろいろ気づきがあります。
「ここマズイな、テスト書いて確認しなくちゃ!」という気持ちになるのでとても重宝しています。
とてもいいツールだと思うのですが、残念ながら BASE社内でもまだ十分に活用されていないのが現状です。ですので、この記事をきっかけに、広めていければいいのではないかと期待しています!
現状ではカバレッジレポート出力が時間がかかる問題があるのですが、今後、自動生成する仕組みを用意できればと考えています。
カバレッジレポートについて
BASEでは、主にCakePHPでサービスが構築されており、ユニットテストも、若干手を加えていますが基本的にはCakePHPに用意された仕組みを利用しています。カバレッジレポートは、その機能を利用して生成しています。
カバレッジについての簡単な説明は、CakePHP クックブックをご覧ください。
(内部的には PHPUnit を利用しています。詳細は こちら )
カバレッジレポートには出力形式がいくつかあるのですが、今回はモチベーションアップが目的なので、人が見てわかりやすいHTML出力を紹介します。
出力されるHTMLページは大きく分けて3つに分類されます。
各ディレクトリ内のファイル一覧 (index.html)
- ファイル毎の大まかなカバレッジ状況を一覧で確認できるページ*1
各ファイルのカバレッジ詳細 (PHPファイル名.html)
- どの関数・行がテストされたかなど詳細を確認できるページ
- 次にどんなテストが必要かを考える際に役立ちます
ダッシュボード (dashboard.html)
- 以下のカバレッジ状況を俯瞰的に確認できるページ
- クラス・メソッドのカバレッジ率 (Coverage)
- コードの複雑度 (Complexity) の分布図
- カバレッジ率の低い順のクラス・メソッド一覧
- リスク (CRAP値) の高い順のクラス・メソッド一覧
- 全体の状況を把握したり、次にどのファイルをテストすべきかをざっと見るのに便利!
テスト作成とカバレッジレポート出力
では、実際にレポートを出力して内容を見てみましょう。
まず最初に、とあるメソッドに対してテストを1つ書いてみました。
<?php public function testView() { // テスト対象を実行 $this->testAction('/posts/view/1', ['method' => 'get', 'return' => 'contents']); // とりあえず、ステータスコードの確認 $this->assertSame(200, $this->controller->response->statusCode()); // その他、なんらかの結果の確認... }
この時点で、カバレッジレポートを出力してみます。レポートを見ると、どうやら一部実行されていない行があるようです。 (注:緑の部分がテストされた行で、赤い部分が未テストな行です。赤い部分をなんとか消したくて、ウズウズしてきますね!)
未テストだった行を確認してみると、$id
が未指定 (null
) だった場合と、
データーベースに未登録な $id
だった場合の処理がテストされてないようです。
このレポートを受けてテストケースを追加してみます。
<?php /** * @expectedException NotFoundException * @expectedExceptionMessage Invalid post */ public function testViewで、IDが未指定だった場合は例外発生() { $this->testAction('/posts/view/', ['method' => 'get', 'return' => 'contents']); } /** * @expectedException NotFoundException * @expectedExceptionMessage Invalid post */ public function testViewで、未登録なIDを指定した場合は例外発生() { $this->testAction('/posts/view/999', ['method' => 'get', 'return' => 'contents']); }
結果がこれ。
やりました!赤かったところが全部緑色に!これで安心です。
ここで、注意点があります。全部緑色になって喜んでいましたが、緑色の行を増やすよりもむしろテストの内容の方が重要です。 たとえテストが実行されたとしても、ちゃんと動作を確認していなければ意味がありません。あくまで、モチベーションを高め、テスト状況を確認するためのツールと捉えていただければと思います。
明日はデザイナーの森さんです!お楽しみに!