BLOG.tass.io

Selenium RCからWebDriverに移行するための、シンプルな4つの手順

2013-12-13

Selenium Advent Calendar 2013の13日目の記事となります。
私はWebDriverから学び始めたのでSelenium RCについて余り知識がないのですが、直近の問題として興味がある方が多いかな?と予想して、Seleniumのマイグレーションを取り上げてみたいと思います。 稚拙な記事ですが、どうぞ生暖かく見守ってください。。。

Seleniumの今後

今年2013年8月末に、次期Selenium3へのロードマップが公開されました。 ミーティングの議事録も、公式ブログにアップされています。

現行の最新版であるSelenium2では、APIが2系統用意されている状態でした。

  • Selenium1からの実装である「Selenium RC」
  • Selenium2で新たにマージされた「WebDriver」

それが次期Selenium3ではSelenium RCのAPIは非推奨となり、今後は緊急の不具合対応を除いてメンテナンスされない事が決定的になりました。 Selenium1の頃から養ってきたRC形式のテストを、いよいよWebDriver形式のテストに書き換える覚悟を決める時が来たわけです汗

RC形式が悪いというより、WebDriver形式の方がより洗練されたAPIであり、早期に開発のリソースを一方に集中した方が長期的に有効と判断されたと理解しています。 なぜWebDriverの方が良いのかは、公式のドキュメントにも記載があります。

  • WebDriverのAPIの方がよりオブジェクト指向に設計されていて、よりコンパクトにテストが記述できる
  • 可能な限りブラウザネイティブのイベントを利用するなど、よりユーザが操作しているかのようにエミュレーションできる
  • Opera, Mozilla, Googleといったブラウザベンダーが開発に関わっているので、より安定的で、高速な実行を望むことができる

とはいえSelenium RCは、非常に扱いやすいGUIのテストメンテナンスツールSelenium IDEが人気だったこともあり、 RC形式でのテストコードを育て上げているプロジェクトも多いと思います。 今後はIDEに代わって、WebDriver形式でのテストメンテナンスツールSelenium Builderを使ってテストを作成していくのが最良かと思いますが、 すでに積み上げた既存のテストも、資産として活かさなければなりません。

そこで、Elemental Seleniumの記事「How To Upgrade from Selenium RC To Web Driver」を参考に、RCからWebDriverへの移行を実現するにあたっての「4つのステップ」を取り上げてみたいと思います。

Googleの事例

Selenium RC形式のテストを積み上げてきたのは、別に中小の企業だけではありません。 IT界の巨人Googleも、大量のSelenium RC形式のテストを作成してきました。 それでもGoogleは早々に、より洗練されたWebDriver形式のテストへ移行することを決断しました。もともとWebDriverの開発元ということもありますが、さすがの英断です。

そこで移行を監督したのが、Googleのジェイソン・レイバ氏でした。 一日に3万ものユニークなセッションが生み出される巨大なテスト群に対して、彼はテストの中断を最小限に抑えながら、見事に移行を成し遂げました。 彼はこの経験を元に、シンプルな4つの手順に従うことで、移行をよりスムーズに行うことができると語っています。

すべてのコードを一挙に置き換えるのではなく、ステップを踏んで移行していくのがポイントです。

  1. 既存のテストをクリーンナップする
  2. Selenium DriverだけをWebDriverベースに置き換える
  3. 今後新たなテストは、全てWebDriverで書くようにする
  4. Seleenium RCの使用箇所を置き換えていく

彼はこの大規模な移行事例について、Seleniumカンファレンス2013の基調講演にて詳しく語っているそうです。 Youtubeに動画 http://www.youtube.com/watch?v=cSLmfegT36Aがあがっていますので、英語がわかる人はぜひ参照ください。

手順1. 既存のテストをクリーンナップする

"保守が容易なテストは、移行が容易なテストでもある" -- Jason Leyba

移行にあたってまずやるべきことは、RC形式のテストコードののまま、既存のテストをクリーンナップすることです。

クリーンナップのベストプラクティスは、Page Object Patternを使うなど、より良い抽象化を行うことです。 テストの抽象化については「Base Page Objectを使う手法」が紹介されていますので、ぜひ参考にしてください。

『クリーンナップはAPIの置き換え作業と同時にやってしまえばいいじゃないか!』と考えるかもしれませんが、それらは同時にやるべきはないと思います。

もし移行を途中で中断することになっても、クリーンナップしておく自体、これからテストを継続的に実行/修正していく上で恩恵があります。 メンテナブルでないテストはつまり、過去の技術的負債です。移行とは関係なく、これからも使い続ける限りは、いつかやらなければいけないものです。

今後新たにテストを記述する場合の練習にもなりますので、まずは保守が容易なテストを念頭に、一度クリーンナップすることをおすすめします。

逆に、ここで洗練されたテストを書く習得を疎かにしてしまえば、今後も負債を増やすばかりです。 スキルアップと将来の開発スピードの向上に向けて、踏んでおくべき手順でもあると思います。

//いや私も偉そうには言えないんですけどねテヘペロー!

手順2. Selenium DriverだけをWebDriverベースに置き換える

次に、RC形式のテストコードののまま、Selenium Serverの部分だけをWebDriverに置き換えます。

Seleenium RCとWebDriverの、2つのDriverインスタンスを生成するようにして、既存のSelenium RCのテストコードを保ちつつ、WebDriverの環境で動作することを確認していくことになります。

Rubyでの実装になりますが、Selenium Wikiの「WebDriver-backed Selenium」に実際のコードが有ります。 WebDriverBackedSeleniumについては、公式のドキュメントにも記載がありますので、参考にしてください。

手順3. 今後新たなテストは、全てWebDriverで書くようにする

ここまで来てからやっと、今後の新しい機能に対するテストは全てWebDriverで作成するようにします。 メンテナブルなテストは手順1.でひと通り考えているはずですし、WebDriverで実行する環境周りも手順2.で整っているはずです。 WebDriverのAPIは、このTransformation from Manual tester to a Selenium WebDriver Automation specialist !!!の記事も参考になると思います。

手順4. Seleenium RCの使用箇所を置き換えていく

WebDriverでのテスト作成が軌道に乗った上で、いよいよ既存のテストを置き換えていきます。

既存のテストが失敗するように破壊してから、WebDriverでのテストに置き換えていきます。 ここが正念場で、時間もかかると思います。この部分以外は全てWebDriverに移行できていますので、一気に置き換えようとはせず、落ち着いて、徐々に置き換えていくことが肝要だと思います。

落とし穴

この移行ステップの中で気をつけるべき落とし穴も、幾つか紹介しておきます。

alert()の処理には互換性がない

JavaScriptのwindow.alert(..)window.confirm(..)でアラートを表示させた場合の処理は、Selenium RCとWebDriverでは全く異なります。互換性の欠片もありません…。 ここは覚悟を決めて、完全に書き換えるつもりで見直しましょう。

暗黙的な"待ち"を考慮する

WebDriverは、ページのロード等、暗黙的に待機が入るケースがあります。

Bindingに使うライブラリにもよるかと思いますが、暗黙的に待ちが入るケースでは冗長なwaitは極力削除して、綺麗なコードを保つようにしましょう。

ただ、参照したい要素を明示的に待つことも、そう一概に悪い考えではありません。 APIによっては暗黙的な待機が入るケースもあると意識した上で、シンプルかつ再現性があるテストを作成するのが良いと思います。

大雑把なテキスト取得をしない

検証を行うために<body>の中のテキストを全て取得するのは、ちょっとやり過ぎです汗

WebDriverで全テキストを取得するのは、特に実行時間がかかってしまいます。 body全体を取得するのではなく、必要なテキストを持つ要素を検索し、その中のテキストを取得するようにするべきです。

JavaScriptの使い過ぎに注意

WebDriverベースのSeleniumは、まだ改善の余地があるツールである事もありますが、パフォーマンスがあまり考慮されていません。

やろうと思えば、テストからSelenium Core APIを使って独自のJavaScriptをページに流し込んで実行することもできますが、実行速度が著しく低下します。 テストからJavaScript流し込むのは最終手段にするべきで、他に実現可能な方法がないか最大限検討しましょう。

そして、最も難しい課題

Googleの事例でも、移行にあたって最も難しかったのは技術的な部分ではなく、人的な部分だったそうです。

例えすぐに使える環境が整っていて、充分にドキュメントも揃っていて、APIが使いやすいものであっても、実際にチームがWebDriverを採用するには時間がかかります。 ジェイソンと彼のチームは、ご褒美を用意したり/鞭を打ってやらせたり/もう力技で強引にやっちゃう等、様々な策を講じて移行に成功しましたが、それでも進捗は芳しいものではありませんでした。

これらの手順を参考にすることで計画的に取り組むことはできるでしょうが、それでも険しい道だと覚悟する必要がありそうです(つд⊂)エーン

先人の知恵からインスピレーションを得るためにも、私ももう一度ジェイソンの講演を見直してみたいと思います。。。

参考リンク

最後に

Selenium Advent Calendar 2013の13日目は以上となります。 次は yukayasui さんです!よろしくお願い致します。

記事の元にした Elemental Seleniumは、Seleniumに関する記事を毎週配信しているようです。 機械翻訳で何となく内容がわかる程度でも大変参考になりますので、みなさま是非、メール購読してみましょです!(●´ω`●)


Michael Kuroneko

Written by Michael Kuroneko. Follow me on twitter, github.