そもそもなぜテストを自動化するのか
セッションの冒頭で、石原氏は「なぜ、そもそもテストを自動化するのか」と問いかけた。
「一番大きなメリットは、人的・コスト的なメリットを生み、開発の効率化が期待できるからです。自動テストと手動テストには、いくつか異なる点があります。自動テストであれば24時間365日やってくれて、書いてあることはしっかり実行してくれる。何より、スピーディに実行してくれます」と説明した。
一方で、テスト自動化にはデメリットもある。まず、テストスクリプトを書いたりテスト環境を整えたりと初期導入コストを考える必要がある。さらに、常にテストが成功する状態を保つために、自動テストの保守運用体制の確保が不可欠になるのだ。
ここで石原氏は、デブサミ2022夏で実施したアンケート調査の結果を見せた。「これまで、テスト自動化経験がありますか?」という質問では、「ある(現在も利用)」が44%ともっとも多いが、「ある(現在は使っていない)」が30%となっていたのだ。
さらに「テスト自動化について、今どんな課題を抱えていますか?」という質問では、スキル不足・リソース不足など多くの課題があがっていた。
「使い続けていないという声が多かったのが今日のセミナーのポイントですね。使い続けるために問題になってくるのは、人の問題とメンテナンスの問題です。この2つが一番大きなボトルネックになっています」
テスト自動化の計画:スコープと解決したい課題を明確に
1番目のポイントは、テスト自動化の計画フェーズについてだ。テスト自動化で何を解決したいのか、スコープと解決したい課題を明確にすることが重要になると説明した。
「何を自動化するのかを整理する。これは自動化においてすごく重要なところです。自動化には向くところと向かないところがあるからです」
テストは、その対象によって単体テスト・APIテスト・機能テストなどに整理できる。このテストの種類によって、実行頻度とカバレッジが異なり、自動化に向くのは実行頻度とカバレッジの高いところ、つまり単体テストとAPIテストのレイヤーになるのだ。
なぜ、ここがテスト自動化に向いているのか。それを説明するために石原氏は、DevOpsバグフィルタという考え方を紹介した。バグフィルタでは、単体テスト・結合テスト・E2Eテストといった階層になっている。各フィルタの粒度と範囲も異なっており、単体テストは粒度は細かいが範囲が狭く、E2Eテストは粒度は荒いが範囲が広くなっている。
「ちょっと気持ち悪いと思うかもしれませんが、ここに上から害虫のタマゴが降ってくると考えてください。単体テストでしっかりと害虫のタマゴを見つけると、次の段階で孵化する害虫を減らすことができます。結合テストで孵化した害虫を見つけられると、次の段階で成虫が少なくて済むんです」
このように単体テストや結合テストのフェーズで細かく網羅的に繰り返しテストをしたほうが、費用対効果が高くなる。
「もう1つ、テスト自動化で何を解決しようとしているのか、これもしっかり押さえておきたい話です」
つまり、テスト自動化の目的を定義することで、どのような手段を採用すべきか明確になるのだ。
例えば、デグレードが頻発してテスト工数が増えているのであれば、単体・結合・スモークテストを強化しながら、開発プロセスに自動化を組み込み頻度を向上させることが考えられる。テストエンジニアのスキルにバラツキがありテストミスが多ければ、機能テストやリグレッションテストを強化する。クライアントから品質が低いという評価を受けたのであれば、自動化によってスピード・頻度・コストの課題をクリアにして、人による高度なテストを十分に実施するコストを確保するといった具合だ。
「うまく行かなかった例では、とりあえず自動化、何でもやっちゃえが多くなっています。テストの自動化を計画するときは、スコープと解決したい課題のところを明確にすることで、どこを自動化するのか、どこの自動テストをちゃんとやるのか見極めることが重要になります」
テスト自動化の実装:テスト自動化をスモールスタートさせる方法
2番目のポイントはテスト自動化の実装フェーズについてである。ここからは、バルデスの江添氏が、テスト自動化の実践的な内容を説明した。
「テストの自動化では、スモールスタートを意識することが重要ですが、その進め方も大切になります」
テストの自動化では、簡単に済むところもあれば技術的に難しい仕様が入っているところがある。そういったところにかかり切りになると、他の機能のテストの実装が後回しになる。一方で、手を付けやすい静的なページの実装を進めるとテストの効果が感じにくくなるのだ。
「そこで、これから自動化を導入する場合は、徐々にカバレッジをあげていくことをオススメしています」
具体的な手順はこうだ。最初に、同じ粒度で中機能から1つできることを自動化実装する。このときバリエーションは無視する。続いて、中機能に関連する画面について最初の実装したテストに含まれない画面確認を自動化実装する。それから、最初に自動化したできることのバリエーションの自動化を実装して、最後にできないことのバリエーションを自動化実装する。つまり、大きな網で機能を網羅していって、段階を追って網目を小さくしていくイメージだ。
「闇雲に作っていく自動化の落とし穴に陥ってしまうことが多いので、最初の段階では粗くそろった粒度で実装して、段階を追って粒度を細かくするように、スモールスタートであっても進め方を考えることが大切になります」
テストの見える化:内容・操作と判定条件とスクリプトを同期させる
3番目のポイントは、テスト自動化の実行フェーズについてである。
「ここでのキーワードはテストの見える化ということです。テストを自動化して実行していると実行している内容が分からないという問題が出てくることがあります。テストは自動実行できているけれど、どんな内容なのか作った人にしか分からくなって属人化してしまうなんてことがよくあります」
このような問題が起こる原因は、テストケースとテストスクリプトが一致していないからだ。そのために、テストスクリプトと実際にテストしたい箇所が食い違っていても把握できない。また、テストに合格しても安心できなくなってしまうのだ。
そのためには、何をテストしたいかの内容や手順・判定条件をテストケースとして明確にして、そこからテストスクリプトを作成するようにテストケースの同期を取る必要がある。テストしている内容を見える化すればテスト漏れやテストミスの軽減につながるのだ。
江添氏は、ここでテストケースとスクリプトの具体例を示した(次図)。ログイン画面で正しくないアカウント情報を入力した場合、「アカウントが正しくない旨のエラーメッセージ」を表示するテストケースだ。
図の下側がテストスクリプトになっている。これは、Selenium + Javaで実装している。このスクリプトを見ると「QBook ID(メールアドレス)とパスワードの組み合わせが正しくありません。」と、より厳密な記述になっている。そのため、ログインエラーが出ても、エラーメッセージの仕様が変更されて文字列が一致しなくなっているのか、別の原因なのかスクリプトを見ないと判断できなくなっているのだ。
さらにスクリプトでは、IDに入力した値が空になっているかチェックしているが、これはテストケースに記述していない。
「こうした不整合があると、仕様変更などがあった場合に問題が発生したり、OKになっていたりするけど本当に問題がないのか確かめる必要が出てきます。その解決策として、弊社のT-DASHというツールでは、テストケースを日本語で記述すると、そのままスクリプトの形で動かすできるようになっています」
テスト自動化の保守:定期的に実行して、自動テストが成功する状態を保つ
4番目のポイントは、テスト自動化の保守フェーズについてである。
「テスト自動化のよくある問題として、作りっぱなしで、いざ使おうと思ったら動かないという現象があります。テストを一生懸命やらなきゃいけない時期があっても、一段落して、次のバージョンアップ開発が終わってからそう思ったら全然動かない。これは本当によくあるんです」
このような現象が起こる原因は、テストケースやスクリプト・自動化の環境・実際のテスト環境などに齟齬があるためだ。また、自動テストが失敗したら間に合わせで修正して、何とか動くようにするため、自動テストなのに時間がかかってしまうことも少なくない。
テストする環境をきちんとメンテナンスして、定期的に実行して自動テストが成功する状態を保つ。つまり、自動テストの保守の負債をため込まないことが重要になると江添氏は説いた。
事例から学ぶ、テスト自動化における成功と失敗の分かれ道
5番目のポイントとして、テスト自動化の実例を紹介して、テスト自動化における成功と失敗の分かれ道を解説した。
「テストのコストを削減するには、繰り返し利用が見込まれる部分の自動化が重要です。同じ操作を繰り返すテストケースなのか、何度も実施するテストなのか、きちんと精査した上で、効果的なところから進めていくことが大切です」
ここで意識する必要があるのは、自動テストを一回やるだけで元が取れることは、ほとんどないと江添氏は説明した。何回か繰り返すと、実行時間が短縮されて、その繰り返しの積み重ねによってメリットが出てくる。
そして、テスト自動化が効果を発揮しなかった事例を1つ紹介した。
この例は、大規模システムのマイグレーションで、機能テストを自動化することで、現行システムと新規システムを比較するコストを削減すると共に、人的ミスによるテスト誤りの防止を目的としていた。そのために、約20万ものテストケースを自動化した。その結果、テスト期間内にすべての確認を終了でき、ローンチ後もユーザー不具合は一切発生しなかった。
「このようにプロジェクトとしては成功したのですが、テストの自動化としては失敗事例としています。20万件ものテストケースを自動化したために、コピースクリプトが大量に発生しており、保守性が低くて再利用が難しくなっていたからです」
せっかく導入したのに再利用ができないため、ROIは20%程度にとどまった。
続いて、テスト自動化の成功事例を紹介した。こちらは、膨大な組み合わせ数のチャットボット用FAQを最小のテストシナリオで自動化して回答品質を向上させた。チャットボットであったため、同じ操作を反復することが多くなっており、スクリプト2本と4400パターンのテストデータを用意して、実装コスト4人日で自動化を実現したのだ。
その結果、1回のテスト実行でROIは100%となった。チャットボットを修正した時も、同じテストを使い回すことができ、非常に大きなコストメリットが得られたのだ。
では、テスト自動化の失敗と成功の分かれ道は、どこにあったのだろうか。
「失敗と成功の定義にはいろいろな観点が考えられます。テスト自動化を継続する場合のコストで見ていくと、同じ操作を繰り返すテストの自動化が非常に効果的だといえます」
開発チームにおいてテストの自動化は重要性が高いという認識が広がっているが、なんとなくテスト自動化を始めて、継続の難しさを感じているエンジニアやPMにとって、大いに参考になったのではないだろうか。
テスト自動化を継続していくことは決して簡単なことではないが、あらかじめ自動テスト環境を保守する工数を計画に盛り込むことが大切になる。システムの運用を安定的に続けるにはコストがかかるが、自動テストの維持もそのための重要な要因になると、あらためて感じたセッションだった。