Chat Dealerの開発と運用

川又由雅氏(以下、川又):それでは「テスト稼働の削減とフロントエンドの品質担保を行うE2Eテスト」について発表いたします。よろしくお願いします。

まず私の簡単な自己紹介からしたいと思います。私は川又由雅と申します。2018年に新卒入社でラクスに入社しました。今年で3年目になります。現在はChat Dealerの開発と運用に携わっていまして、バックエンドとフロントエンドを取り扱っています。今年は学習が趣味で、Vue.jsを用いてSPA(Single Page Application)を作ったりしていました。

本日話す内容ですが、まずChat Dealerについての簡単な紹介と、あとはChat Dealerが抱えていた課題について。そして、その課題をE2Eテストによって解決した話と、E2Eテストによって実際に出た効果。あとは、今後やりたいことについてお話しします。

Chat Dealerが抱えていた課題

まずChat Dealerですが、サイトに専用スクリプトを埋め込んで利用するチャットシステムです。これで、ボットを用いて自動的に応答することもできます。

前提なのですが、チャットボット機能が存在します。チャットボット機能は、エンドユーザーからの質問に対して、想定した回答を返す仕様になっています。チャットシステムにとってチャットボット機能はプロダクトの大前提であるため、想定どおりに動かないことはあってはならないです。そのため、チャットボットのテストは極めて重要となります。

Chat Dealerは、毎月新機能をリリースしていて、ほぼ毎月と言っていいぐらいチャットボットになにかしらの改善が加えられています。チャットボットに不具合は絶対出せないので、毎回リリースするたびに、テストが必要となります。

そこでChat Dealerが抱えていた課題です。チャットボットの機能のテストを、かつては手動でやっていました。これがものすごく大変で、なんで大変だったかと言うと、テストケースが多いことなんです。にもかかわらず、毎月新機能をリリースするので、機能がどんどん追加されていきます。その結果、ケース数が膨大になっていきます。

実際に我々がどんなテストを行っているかと言うと、まずチャットボットの前提条件に関するテストケースです。この前提条件というのは、チャットボットが実行するトリガーとなる条件です。

続いて実行条件に関するテストケースです。これは、チャット訪問者の情報や環境により実行するかしないかが分けられます。

そしてこれは、アクションの種別によるテストケースです。メッセージ送信や問い合わせフォームの表示などがあります。

この3種類のテストケースを、さらにいろいろなパターンに分岐させてテストを行っていきます。

E2Eテストの導入

以上のテストで、全テストケース数は642個となります。E2Eテスト導入前は、テストを手動でやっていて、16時間ほどかかっていました。前述の通り、Chat Dealerは毎月新機能をリリースしているので、1年で16時間×1年で、12回リリースするということなので、1年で合計192時間かかっていました。

加えて手動でテストケースを行うと、どうしてもテストケースの漏れが発生する可能性が出てきます。テストの品質は、実施する人やそのテストをしている状況によっても異なってきます。そこで、E2Eテストを導入しました。

まずE2Eテストを導入する目的は、テストにとられる稼働の削減と、テストの品質を揃えることです。これでテストケースの漏れを防ぎます。内容としては、チャットボットのテストを自動化します。どうやってやっていくかと言うと、ブラウザ環境を用意して実際にチャットを設置しているページにアクセスします。ページのHTMLの要素をもとに、テストを行っていきます。

実際に例を1つ示すと、実際にメッセージを送信すると、チャットボットによるメッセージがそれによって送信されます。その送信されたメッセージが、ちゃんと画面に表示されているかというテストを行っていきます。

Chat Dealerの技術スタック

技術スタックについてです。言語はJavaScript、ミドルウェアはNode.jsを使っています。自動化のツールとしてはPuppeteerを使用しています。ではなぜ、Puppeteerを自動化のツールとして使用したかと言うと、これは導入コストがあまりかからないからです。

今(スライドに)表示しているメリットがあります。学習コストがかからなかったり、インストールが楽だったり、環境の準備が楽だったりというメリットがあります。

実際にSeleniumを使う案もあったのですが、Seleniumにはいろいろ必要なライブラリやミドルウェアがあって、環境構築が大変そうなので、結果的にPuppeteerを使うことになりました。

続いて、環境の準備です。まずはNode.jsをインストールします。バージョンは8以上を使用します。続いてE2Eテスト用のディレクトリを用意して、その中でnpm installを実行して、Puppeteerをインストールします。

続いて、実行コマンドです。E2Eテストでは作成したすべてのテストファイルを一括で実行します。あらかじめ、package.jsonにテストの一括実行用のコマンドを設定しておいて、それをnpmで実行します。そうすることで、テストが一気に実行されるので、チャットボットの設定などを1回1回終了する隙間の時間を省くことができて、その分コストが削減できます。

E2Eテスト導入の効果

そうすることで得られた効果について。E2Eテストにより、チャットボットのテストの工数は16時間から2時間程度に削減できました。これを実際に毎月リリースで、年12回のリリースに換算すると、14時間の削減×12ヶ月で168時間となり、1年で168時間もテストにかかる工数を削減できます。

このテストの自動化にかかった工数は86時間ぐらいで、86時間÷14時間(1回で削減できる時間)を計算すると、だいたい6.1ぐらいになりまして、Chat Dealerは月1回リリースしているので、半年ちょっと運用すればペイできます。

あとは、効果としてリリース前に不具合を検知できました。ちょっと詳細については省略します。特定条件が組み合わさったときに、チャットボットが正常に動作しなくなるという致命的な不具合になります。これ自体は、発動条件がマニアックになっているのですが、網羅的・自動的にチェックできるE2Eテストのおかげで、事前に検知できました。

今後やりたいこと

そして今後やりたいことについてです。今はチャットボットの機能をE2Eテストで自動化したという話だったのですが、チャットボット以外の機能もE2Eテストで自動化したいと思っています。テストを自動化したい機能は、実際にエンドユーザーと対話するスタッフ側の機能や、チャットの設定などのメンテナンス、あとはレポートなどの管理系の機能を自動化したいと思っています。

以上の機能のケースが428個で、このチャットボット以外の機能テストにかかるテスト工数が、1ヶ月あたり16時間ぐらいになります。計算したところ、16時間からこのチャットボット以外の機能は約7時間にまで削減できて、約9時間の削減が見込めています。毎月リリースしているので、これは1年で削減できるのが、9時間×12回のリリースで年間108時間の削減効果が見込めます。

続いて、不安定なところを解消したいと思っています。E2Eテストが不安定な原因がネットワーク遅延で、画面が表示される前にテストが進行してしまうことがあります。あとは、たまにJavaScriptファイルが取得できないことがあります。今後やりたい対策として、テストの待機設定を見直していきたいと思っています。

続いてリファクタリングです。このテストの自動化を突貫で実装してきた結果、テストコードが粗くなってしまっているので、いつかコードをきれいにしたいと思っています。

E2Eテストを導入してよかった点・苦労した点

実際にE2Eテストを導入してみてまずよかった点。Puppeteerの導入コストがかからなかったことと、あとはチャットボットの動きはインプットとアウトプットがともに文字列、インプットがエンドユーザー側が送信するメッセージで、アウトプットがチャットボットにより送信されたメッセージです。この定義が楽です。このおかげで、テストがしやすくなります。

逆に苦労した点としては、私が初めて実装したとき、Node.jsについて知識が少なかったため、不明点が多く、詰まってしまいました。解決策としては、Node.jsについて勉強しながら進めていったことと、あとはわからないことがあれば、知見のあるメンバーに質問して解決させました。

あとは不安定なところです。E2Eテストが不安定なために、テストもたまに失敗してしまうことがありました。対策としては、待機設定を設けて、遅延を少しでも防ぐようにしていました。

ちなみにですけど、なぜ最初からE2Eテストを導入できなかったかと言うと、Chat Dealerのプロダクト立ち上げ当初は、テスト駆動で開発しようという計画があったのですが、機能のリリースを最優先したために、テスト構築は後回しになってしまいました。今後は、テスト構築コストとランニングコストの比較を適切なタイミングで行っていきたいと思います。

最後に、E2Eテストはインプットとアウトプットがはっきりしているとき、手動で何度も同じようなことをやっているとき、あとは定期的にテストタイミングが発生するときに、効果が絶大となります。費用対効果が見込める場合は、ぜひともE2Eテストをやるべきだと思います。

以上で発表をおわります。ご清聴ありがとうございました。

質疑応答

藤澤貴之氏(以下、藤澤):川又さんありがとうございました。ここから質問や、みなさまの感想なんかを拾っていきたいと思います。

池田智裕氏(以下、池田):「テストでバグが見つかったときはすべてテストをやり直したのでしょうか?」という質問が来ていますね。1つバグが見つかったらどこまでテストをやり直すのかみたいなことですね。

川又:例えば1つバグが見つかった場合、そのバグが影響するところはすべてやり直します。

池田:影響範囲を見てその分は全部テストするんですね。また影響範囲を見るのも難しそうですね。

「自動化テストの実施時間が2時間で不安定になった話があったんですが、それも含めて2時間ということなんですか?」という質問が来ています。

川又:そうですね。不安定でたまに失敗してしまいますけれど、それも含めて2時間程度になります。

池田:ありがとうございます。「Puppeteerは金銭的な導入コストは無料ですか?」という質問も。Puppeteerは有料ですか?

川又:すみません、あまり把握していないのですが、おそらく無料で始められると思います。

池田:ありがとうございます。「PuppeteerということはChrome以外では検証していないのでしょうか?」という質問も来ています。こちらはどうでしょうか?

川又:そうですね。Chrome以外ではやっていないですね。

藤澤:まぁでも、EdgeとかFirefoxとかを使ったテストもやってはいるんですよね。

川又:やってはいますね。例えば単体レベルのテストとかですと、画面上、JavaScriptやそういったCSSが影響してきそうなものとかは、マルチブラウザテストが必要になってきます。

池田:もう1つ気になる質問があります。「ユニットテストは導入されていますでしょうか?」と。「E2Eテストとはどのように棲み分けをしていますか?」というような質問が来ていますね。

川又:PHPによるユニットテストですね。PHPUnitでやっています。

池田:画面の動きのほうは、こっちのPuppeteerでE2Eをやっているということですね。

川又:そうですね。フロントエンドの品質担保はPuppeteerでやっています。

池田:「テスト自動化によって手動に比べて漏れなどがあると思ったんですが、特になかったかでしょうか?」という質問も。これはどうですか? 逆によくなったとか、実はちょっと漏れが出たとか。

川又:特にあまりないですね。漏れが増えることはなかったかなと。

藤澤:そのE2Eテストだけで全部カバーしているわけじゃないからですよね。

川又:そうですね。全機能自体はカバーできていないですが、チャットボットの機能に関してはほぼ網羅的にテストできているかと思います。

池田:「E2Eテスト実行時のカバレッジは何パーセントぐらいを目標にされていますか?」。たぶんちょっと難しい質問ですね。例えばチャットボットに関してはどうですか? 今回やろうとしたところに関してはカバレッジは何パーセントぐらいいきましたか?

川又:カバレッジは特に……。質問に答えるとするならば、目標は特に決めていなかったと思います。

藤澤:川又さん、もともとこの手動でやっていたテストケースというのは、どうやって起こされたものなんですか?

川又:そうですね。もとからその機能をリリースする前にと言いますか、その全機能テストとか、あとはチャットボットのそのパターンとかは一応テスト仕様書としてまとめていて、それを基にテストを行っているといった感じです。

藤澤:それはユーザーの操作は割とシナリオベースみたいな感じなんですかね?

川又:そうですね。今はシナリオベースに実行するみたいな感じで、この条件でテストするといった感じでまとめています。

藤澤:はい、わかりました。ありがとうございました。

川又:ありがとうございました。