<-- mermaid -->

テストカバレッジはテストの家計簿だよねって話

前書き

こんにちは。NewsPicksの一人目QAエンジニアの西薗(@yurizono)です。

NewsPicks Advent Calendar 2022 の9日目をお送りします。

qiita.com

この記事に書かれていること

2022年に私が取り組んだ、リグレッションテストの改善活動についてお話します。家計簿の話はちょびっとだけします。

テストケースに問題あり

私の入社以前から、NewsPicksでは毎月、アプリのリグレッションテストを外部ベンダーさんにお願いしていました。私がこの運用を引き継いだのですが、数回の実施を通じて、ここで使われているテストケースにいくつか課題が見えてきました。

可読性

まず、読みづらい。私も2年弱ほどテストベンダーに所属していたので分かりますが、月に一度の案件だと、毎回同じテスターをアサインすることは稀です。テストリーダーですら毎回違うかもしれません。そうなると、いわゆるハイレベルテストケースは実用に耐えません。ハイレベルテストケースとは、テスト内容を抽象的に表現したもので、簡単に言うとそのアプリに詳しい人間でなければ具体的な手順が分からずテストできません。

従ってこの体制ではローレベルテストケースが必要です。ローレベルテストケースは具体的なデータや手順が明記されており、アプリに詳しくない人間でもテストできる一方、詳しい人間にとっては記述が冗長過ぎて読みづらいというデメリットがあります。ハイレベルとローレベル、この2つの隙間を埋めるために、みな一生懸命にスプレッドシートの端の方に「テスト観点」とやらを書き込んだりするのですが、長い期間にわたってその項目が健全にメンテナンスされていることは稀です。NewsPicksでも例に漏れず、「テスト観点」とやらに書かれた内容は画面名だったり操作だったりと統一感がなく、可読性には寄与していませんでした。

モグラ叩きを止めよう

次に、テストケースが読みづらいことによって、何をテストしていて何をテストしていないのか誰も知らない、という状況に陥っていました。ある案件では、リグレッションテストはしっかり回したものの、「アカウント作成時のメールアドレス認証に失敗する」というバグがリリース後に発覚。そう、リグレッションテストと謳いながら、そんな基本的なケースがすっぽ抜けていたのでした。そしてそのことに私を含め、誰も気付かなかったと。そりゃそうです、テストケースを通して読んで、何がテストされているかを確認するだけでも、数人がかりで10時間以上かかる代物だったのですから。

さて、何がテストされていて何がテストされていないのかが分からないと、何が困るのでしょうか。

先述の「アカウント作成時のメールアドレス認証」に関するテストケースを追加したとしましょう(実際、発覚後すぐにケースを追加しました)。さて、これによりテストの穴がひとつ埋まりました。しかし、まだ他にも穴がありそうな気配がしますね。しかし、どこに穴があるのか分からない。分からないから、その穴が埋まるのは「その穴にはまって本番でバグを出したとき」でしょう。これぞモグラ叩きです。モグラ叩きをQAエンジニアの仕事とは言いたくない、と思った私は、この現状を変えるべく、テストカバレッジを測ることにしました。

なぜテストカバレッジを測るのか?

みなさん、家計簿はつけてますか?なるほど、つけていると。でしたらテストカバレッジは測ってますか?え、測ってない?

家計簿をつけずに家計の健全化を目指すというのは、安いスーパーでまとめ買いしようとか、電気をマメに消さなきゃとか思い付いた節約に励む一方で、不要な保険に月2万円払ったり、SNSを見るだけのスマホに月8000円払うようなものです。これはテストでも同じで、テストカバレッジを把握せずにテストを改善しようとしても、大抵は上手くいきません。

テストカバレッジを測ることで、そのテストに何が足りないのかを知ることができます。また、今のテストがどのレベルにあるのか、つまりとんでもない赤字でただちに大幅なテコ入れが必要なのか、今の調子で改善を続けていけば健全化が見込めるのか、といったところを把握することで、そこからの作戦を立てやすくなります。そして実際に改善活動を始めた後も、毎月少しずつ数字が改善していくのを見て成果を実感することができますし、活動の成果が出ていることを周囲にも主張しやすくなるでしょう。

改善活動

私がやったことは以下の3つ。

  1. NewsPicksアプリの機能を一覧化し、数えられるようにした(=テストカバレッジを定義した)
  2. リグレッションテストでテストされている機能を数えた(=テストカバレッジを計測した)
  3. 足りないテストケースを足した(=テストカバレッジを上げた)

簡単に言うと、まずテストのどこに穴があるのかを把握し、その穴に誰かがハマる前に埋めにいく、という作戦です。言うのは簡単ですが、ゼロから実際にやるのはちょっと大変です。順に説明していきます。

1. テストカバレッジを定義した

何を数えるか

まず、カバレッジを測るためには分母を明らかにする必要があります。テスト対象がソースコードなら簡単で、カバレッジは「テストで何行のコードが実行されたか/全部で何行あるか」で求められます(C0カバレッジの場合)。しかし今回のようなシステムテストで何行のコードが実行されたかを計測するのは骨が折れるので、代わりを探す必要がありそうです。そこで、機能数を出してみることにしました。全て洗い出すことは不可能なので、「私が知っている機能のうち、何%はテストしました」という不完全な指標にはなってしまうのですが、ないよりはマシです。

機能の数え方

さて、「機能」ってなんでしょうか。「ログインする」は機能でしょうか。「無料会員でログインして有料記事をピックしようとすると、課金導線が表示される」も機能っぽいですね。それなら「有料会員がログインした状態で電波のないところに行き、アプリを起動してダウンロードした動画を閲覧できる」も機能ですね。もっと言うと、「アプリ起動直後に表示されるフィードの上から3番目の記事にコメントする」も機能と言えそうです。2番目は動くけど、3番目も動くとは限りませんからね。さて、どこまで機能を洗い出せばいいでしょうか。

もうお分かりの通り、「機能の粒度」を決めておかないと無限に機能が列挙できてしまいます。この粒度を決める作業は意外と大変です。手法は色々あると思いますが、結局は試行錯誤しかありません。

今回は以下の方針で進めました(進めるうちにこうなりました)。

  • 画面に関係する要素は機能として扱わない。

    • 画面Aと画面Bで同じ操作ができるなら、それは1つの機能として扱う。
    • 上から1番目の記事と2番目の記事、などの表示位置の違いは無視する。
  • 機能は、アプリ内の概念に対するCRUDの形式で表現できるものとする。

    • 例:記事へのコメントを作る/取得する/変更する/削除する
    • 例:アカウントを作る/更新する/退会する
  • 分類同士の掛け算は、それが業務上意味を持つ場合にのみ行い、それぞれ別の機能として扱う。

    • 無料ユーザも有料ユーザも外部記事は読めるので、これは区別せずに「ユーザは外部記事が読める」とする(テストケースとしては用意してもよいが、1機能として扱う)。
    • 一方で有料記事は有料ユーザしか読めないので、これは「無料ユーザは有料記事が読めない」「有料ユーザは有料記事が読める」とする。
実際に機能を洗い出す

ということで、機能を列挙していきました。最初は一人でやろうかと思ったのですが、作業量が途方もないので、とりあえず3人、週に2回1時間ずつ集まって進めることにしました。この過程で大量の、知らない機能と巡り合うことになりました。第一弾を作るまでに1ヶ月ほどかかったでしょうか。めちゃくちゃ時間はかかりますが、やって良かったと思います。いまも週一回、継続して機能一覧のメンテナンスは進めており、機能は増えたり減ったりしています。

2. テストカバレッジを計測した

計測方法

さて、機能一覧ができました。次に、カバレッジを計測しなければなりません。しかしテストケースはスプレッドシートで管理されており、要件との紐付けなんて高度な機能は使えません。ここは詳しくは省きますが、ざっくり言うと、洗い出した全ての機能それぞれにユニークなキーを振り、その機能をテストしているテストケースの横にそのキーを記入するという作業をしました。

実際に計測する

作業自体は単純なので、ひたすらやりました。機能の洗い出しと同様、3人で毎週2回、1時間集まって、テストケースを全て読み解き、そのテストが何をテストするものなのかを理解し、該当するキーを記入していきました。結局、全て完了したのは、機能一覧が完成してから3ヶ月が経過した頃でした。

3. テストカバレッジを向上させた

いや長かったですね。しかし、まだカバレッジを計測しただけです。穴があることはわかりました(カバレッジは54%でした)ので、足りないテストをひたすらここから足していきます。なんだかんだ、カバレッジが96%になるのに追加で2ヶ月ほどが必要でした。途中、追加するだけではメンテナンス性が限界だということで、大規模なリファクタリングなども行い、かなり見通しの良いテストケースになったと思います。

改善活動の結果

こうして、機能が一覧化され、リグレッションテストのカバレッジが計測され、それが数ヶ月かけてほぼ100%になったことで、この活動はひとまず区切りがつきました。しかしアプリというのは常に新たな機能追加や削除が行われています。現在はいろんなプロジェクトに顔を出してテストするとともに、新たな機能や改修についての情報を収集して機能一覧に反映させ、リグレッションテストを最新に保つという活動を続けています。数字で前後を比較するのは難しいのですが、この活動をやる前と比べて、かなりテストが頼り甲斐のあるやつになってきた感じがします。

また、機能一覧を整備したことで、QA以外のメンバーも広く浅く機能を知ることができるようになりました。もっとも、今はただのスプレッドシートですので、もう少し見栄えを整えるなどして、機能一覧ポータルサイトみたいなものを作るのも良いかなと思っています。画面キャプチャも一緒に見せるなどすれば、より可読性が増すでしょう。オンボーディングにも役立ちそうです。

おわりに

今回はリグレッションテストの品質改善を進めるにあたり、テストカバレッジを活用した話をしました。アプローチとしては普通だと思いますが、実際にそれを半年かけてやったことのある方は意外と少ないのでは?と思い、共有させていただいた次第です。

今後もQAを進める中で、トライしたこと、うまくいったこと、そして失敗したことも含めて共有していきます。

Page top