失敗からはじめるSelenium

selenium-logo

こんにちは。kintone 開発チームの長谷川&宮田です。 みなさんテスト書いてますかー?

品質の高い製品をリリースし続けるためにはテストを書くのは当たり前。でも実際にテストを書いたりメンテナンスをするのは大変なこと。特に、ユニットテストではなく Selenium のようなブラウザテストはコストが高く、運用が難しい面も。。

kintone チームでも Selenium を使って自動化試験を行なっています。 ここ1年ぐらいで随分テスト周りの仕組みが整備され、製品の品質向上に繋がっていることを実感していますが、 最初の頃は失敗も多く自動化試験としてはあまり機能していませんでした。今回はそんな kintone チームの自動化試験への取り組みの失敗とその改善について紹介したいと思います。

Selenium の失敗あるある

始めに昔の取り組み(失敗談)をいくつか簡単に紹介します。

テストの目的が曖昧

一番最初はテスト項目の設定から実装まですべてをPGが行なっていました。当時はJavaScriptのユニットテストもほとんど書いてなかったこともあり「画面上の操作でここは不具合多そうだな」という箇所のテストがメインでした。

その後自動化試験の品質を高めようとQAが試験設計した項目をPGが実装というスタイルに変わっていきましたが、この頃は機能試験の意味合いが強く網羅テストまでやってしまっていたため、メンテコストや実行時間の増大に繋がりました。。

テストをいつ書くの?

開発FIX直前の一週間にPG全員でえいやっとテストを書いたりしてました。それまでは放置してるので、新機能の不具合や既存機能のデグレの発見が遅れたり、過去のテストのメンテナンスもきちんとできていなかったため、テストが壊れた状態で1ヶ月(!?)とか普通にありましたね。この時点で自動化試験の役割をほぼ果たしてなかったです。。

実行はするけど

1日1回夜中にJenkinsで実行させていました。この頃は4ブラウザの自動化試験の実行に2時間30分もかかっていて、実行時間がテストのメンテナンスのネックの要因の一つでした。時間のかかっていた原因はこんなところでしょうか。

  • テストを逐次実行していた
  • 網羅テストなどテスト項目が多すぎ
  • テストの事前準備(初期データ)も全部 Selenium で実行

またテストに失敗したらメールで通知されるけど、それ以上の強制力はなかったので、テストが壊れていても放置する習慣がついてしまっていたのがまずかったです。

改善の取り組み

今ではここまでの失敗を乗り越えて開発プロセスに Selenium を取り込めたので、改善の取り組みについて紹介します。

目的を明確にしてみる

いろいろ収拾がつかなくなっていたので、いったん目的を整理してみました。

勉強会で継続的デリバリー実践アジャイルテストを読みつつチームで話し合い、GUI を通したテストはコストが高いので、目的は受け入れ試験の自動化に絞ることにしました。不具合の改修確認を Selenium テストで書きたいという声もあったのですが、そこはできる限りユニットテストや API テストでカバーしていくことにしました。勉強会は QA とも合同で行ったのですが、自動化する上でなにが必要か意識を合わせつつ仕組みを作っていけたので、よい取り組みだったと思います。

本のトピックについて話し合いつつ、具体的なタスクに落とし込めたのがよかったです。
本のトピックについて話し合いつつ、具体的なタスクに落とし込めたのがよかったです。

開発プロセスとの融合

最初の目標は、開発フェーズが終わる時点で受け入れ試験がすべて自動化されていることにしました。試験が始まる段階で受け入れ試験がオールグリーンになっているのが理想だからです。

現在では、開発は以下のような流れになっています。

  1. PM が要件を決める
  2. QA が要件のシナリオを元に受け入れ試験を設計する
  3. PG が実装と受け入れ試験の自動化を行う → 実装完了!試験フェーズへ!

完全に分業されているように思われるかもしれませんが、実際には、PM/QA/PG がコミュニケーションをとりつつ進めていきます。自動化できなかった受け入れ試験は、従来通り QA に手動で試験を行ってもらいます。QA でなく PG がテストを自動化しているのは、機能の実装とテストの実装・メンテを並行していくのに効率がよさそうというのが主な理由で、他にはリソースの余裕などチーム事情的理由もあります。

本格的に始める前に Selenium 以外の GUI テストツール (Sahi など) も調査してみたのですが、PG が書くということから結局 Selenium WebDriver に落ち着きました。他のツールにも魅力的な点はあったのですが、やはり情報量の多さから現時点では Selenium が無難かと思います。

テスト実行環境の整備

開発プロセスに取り込むにあたり、マスターブランチに push されるたびに Jenkins 上で Selenium テストが流れ、結果が弊社製品上のスレッドに投稿されるようにしました。仕組み自体は過去の記事に書いたとおりです。

ここで問題になったのは、やはり実行時間です。push するたびに何時間も待たされるとマージ行列ができてしまって大変です。現在では、並列化などをがんばり、一回の実行時間は20分台に抑えられています。これぐらいだと、ストレスも少なく運用が回る印象です。テスト数が増えていけば実行時間は増えるので、実行時間の短縮はこれからも探求が必要だと考えています。

デプロイメントパイプライン
kintone チームのデプロイメントパイプライン。自動テストが通り、デプロイが成功するまでがタスクです。

また、初期データの作成を API を叩いて生成するようにしました。GUI を通して生成すると時間がかかりすぎるし、DB のダンプはメンテが大変なので、API を叩くのがちょうどよいという判断です。今のところ特に問題は感じていないので、この取り組みは成功だったと思います。

実践編お悩み Q&A

ここまでプロセス的な話が中心になってしまいましたが、私たちが Selenium テストを実装・メンテする上でぶつかった技術的な問題とその対策について紹介します。

UI 変更に弱い

Selenium がメンテできなくなる原因としては、UI に大きな変更が入ってテストのあちこちが壊れるというのがありがちな話です。実際、私たちのチームもメンテ不能に陥りました。。

UI 変更に弱いのは、UI とテストが密結合になっているのが原因です。これを回避するために、ページオブジェクトパターンを使用して UI 操作に責任を持つレイヤを用意し、UI とテストを疎結合にすることでこの問題は改善されました。

安定しないテスト

XHR で動的に画面を変更していくような Web アプリの場合、どうしてもネットワークの遅延などタイミングによって安定しないテストが出てきます。テスト結果が安定しない状態が続くと、本当の不具合がスルーされてしまう恐れがあります。

個別に安定させていくことも重要ですが、全体の安定化のために各テスト一回までリトライを認めることにしました。ただリトライするだけでなく、リトライしたときに管理アプリに登録することで後から安定しないテストが分かりやすくなるようにしてあります。このあたりの仕組みは、クックパッド様の記事からパクリインスパイアされています。

メールのテストが難しい

Web アプリとメールは関わりが深いですが、送信されたメールの内容を確認することはSeleniumでは難しいです。kintone でも、メール通知機能などあるので、どうにかテストできるようにしたいところでした。

対策として、メールを送信しないで保存するだけの仮想SMTPサーバーを起動して、それをメール送信サーバーとして指定することによってメールの中身をテストプログラム上で確認することができるようにしました。Wiser というライブラリを使用して実現しています。

Selenium テストの恩恵

ここまで読んで、「え、Selenium 大変そう・・・」という印象を受けるかもしれません。たしかに厄介なところもありますが、私たちのチームではその苦労に見合う恩恵が受けられていると思うので紹介します。

工数の削減

自動化について社内のステークホルダーに理解を得るためにも、工数の削減については強くアピールしたいものです。

まず、自動化した試験を QA が手動で試験しなくてよくなります。それに加えて、不具合は前のフェーズで発見されることにより対応工数が大きく違います。不具合登録やトリアージ、再試験といった非生産的な工数が削減されるのは嬉しいものです。

品質の向上

受け入れ試験を一度自動化してしまえば、それ以降は自動化した部分のビジネス的価値が常に保証されることになります。Web アプリの品質は単体テストだけでは保証できず、GUI を通したテストは必須です。

大きな変更への安心感

PG 的に一番嬉しいのは、影響範囲の大きい修正を思い切ってやれるようになることです。受け入れ試験レベルの品質が常に保証されるので、Selenium テストのあるなしで安心感が違います。

おわりに

製品開発プロセスで Selenium テストを実践する上で遭遇した問題点と改善への取り組みについて紹介しました。Selenium は、実際の製品開発での運用の話を聞く機会がなかなかないので、まだまだ手探りで探求している最中です。この中でひとつでも皆さんの参考になるものがあれば幸いです。Have a nice Test!