Seleniumしくじり先生 〜E2Eテストの導入で失敗した話〜


まえがき

E2Eテストを自動化したいこと、あると思います。
特にアジャイル開発を行なっていく際には、予期せぬregressionを防ぐためにも必須のツールでしょう。
毎回ポチポチポチポチ画面テストするのは工数的にもモチベーション的にも最低です。

そう考え、私はSeleniumによる自動テストを1ヶ月かけて設計・実装しました。
そして最初は「ぬるぬる自動操作されてて感動した😆」「これで工数めっちゃ削減されるな👍」
そんな声をチームメイトからもらえ、「いいもん作ったな〜俺」とか内心ドヤ顔でした。

ただ数ヶ月もしない内にテストは役立たずになってしまいました。
この記事はなぜ自動テストが無価値になってしまったのかを書きます。
割とSeleniumあるあるな話でもあるので、これからSelenium使おうという方の参考になれば幸いです。

※ちなみに私はJS(+ WebdriverIOというライブラリ)を用いて書いたので、他の言語でSelenium使っている場合と比べて趣が違う可能性があります。

原因1. 信頼性のないテスト

これはSeleniumを使ってみてもらえば分かりますが、Seleniumのテストは
タイミング次第 で落ちます。

どういうことかと言うと、まず前提としてSeleniumでテストを書く際には様々な状況でDOMを選択する必要があります。
動作の再現だったり、テストしたい画面への遷移だったり、テスト結果の確認だったり。
この時問題になるのが、まだ存在していないDOMを選択しようとしてテストが失敗することで、これがまた結構な頻度で起こります。

これを防ぐためには、起きる可能性がある部分(大抵はページ遷移後のタイミング)にそのDOMがマウントするまで
待つような処理を挟むのですが、まあめんどくさいしなにぶん数が多く洗い出しきれない。
心が疲弊してきた私は次第に色んな処理の合間に

browser.pause(300);

とかを挟み出し、テストが落ちないことを祈りながらひたすらテストコードを書き連ねます。

しかし非情にもテスターさんから告げられる「落ちるんですけど」の声。
そして私は彼にこう伝えるのです。

「とりあえず動くかもしれないんで、もう一度回してみてもらえます?」

信頼性のないテストはゴミなのです。
そしてゴミは使われなくなるのです。

原因2. ブラウザの対応状況が微妙

残念なことに私の作った自動テストは全てのブラウザで動作するわけではありませんでした。
Google Chrome、Firefox、Safariという対応状況で、
Edge,IE11には未対応でした。

なぜかというと、言ってしまえば心が折れたため、
「とりあえず一部のブラウザで動作するもの作ってリリースしよう。それだけでも価値があるはずだから
IEとかはあとで対応しよう」と思い自分を納得させ、不完全な対応状況でリリースしました。
(もちろん未だにEdge,IE対応はしておりません😇)

ちなみに折れた理由は色々たくさんあるんですが、以下に代表的な理由を二つ書きます。

EdgeのDriverで click が動作しない

2017年5月時点の情報なので今はどうか分かりませんが、おそらく一番使われるであろう動作 click が動きませんでした
↓こんな感じのエラーが出ます。

Excpetion "org.openqa.selenium.WebDriverException: Element is obscured "

代わりに以下の様な形でクリック関数をwrapすることによって回避しました。
参考: https://softwaretestingboard.com/qna/363/word-around-for-edge-driver-click

    browser.click = (selector) => browser.selectorExecute(selector, function(element) {
        element[0].click();
    });

俺は何をやっているんだろうという気持ちになりました。

IE11のドライバーのタイピングの速度が異様に遅い

尋常じゃなく遅いです。本当に。どれだけ強調してもしたりない。おっっっっっっっっそい。
64bit版使ってると遅くなるみたいです。

参考

私はnodejsでテスト書いてて、npm にある selenium-standalone を使っていました。
そこで、 node_modules/selenium-standalone/lib/default-config.js を開き、
iearchia32 に変更するというハッキーな方法で解決しました。

俺は何を(ry

話が長くなりましたが、結局対応状況の微妙なのが何がいけないかというと、単純に価値が下がることです。
対応ブラウザ半分ならそのまま価値が半分です。
ただ、全部対応しようとするのは本当に茨の道だと思います。
これはSelenium導入時、そしてメンテナンスをしていくに当たって考慮すべき観点かと思います。

原因3. メンテナンスをなめてた

もしかしたらこれが一番致命的かもしれないんですが、
メンテナンスが誰の責務なのかを曖昧にしたまま、ろくに連携もせずツールだけを渡してしまったのが失敗でした。

当然ながら機能が追加/変更されていくにつれ、テストケースも増えたり変わったり不要になったりします。
このメンテナンスのコストをあまり深く考えず、
「これが自動テストですよ、対応してるテストケースは今のところこんな感じですよ」
ということだけを伝えて、後は丸投げしてしまいました。

テスターさんとしては内部のコードとかもろくに連携受けてないし、メンテが自分の責務とは夢にも思いません。
私は私でメンテはよしなにやってくれるのではと思い(今振り返るとホント頭おかしい)、
自分のスケジュールにテストメンテの工数を含めていませんでした。

こんな状態だったので、自動テストはどんどん古くなり、価値もどんどんなくなっていきました。
メンテナンスを誰がどのタイミングでやっていくのか、ということは明確にしておかないと、どんどん廃れていきます。
E2Eテストのみならず他の自動テストにも言えることですが、
単純にツールだけあればいい、ということではなく、それがしっかりと業務に組み込まれていなければ、価値はないんだなと実感した出来事でした。

まとめ

ざっくりまとめると以下を担保できなければE2Eテスト自動化は失敗するというのが所感です。

  1. 信頼性のあるテストを書くべし
  2. なるべく様々なプラットフォームを対応すべし(ただし工数との兼ね合い)
  3. メンテナンスを業務にきっちり組み込ませるべし

E2Eテストの自動化はリターンが大きいことには違いないんですが、結構落とし穴がたくさんあるので、
先のことまで見据えて設計しないと、大分時間を浪費してしまうものだなーと思いました。
皆様も取り組む際にはお気をつけください。

余談: Testcafeが銀の弾丸かもしれない

最近なにやら Testcafe なるものが流行っているらしく、READMEには

Works on all popular environments

とか

Stable tests and no manual timeouts

とか、まるでSeleniumの痛いところを解消してくれるような文字が並んでいて銀の弾丸感があるので、
まだ触ってはいないんですが、こちらへの乗り換えも検討しています。
使っていないのであんまり無責任にオススメできないんですが、これからE2Eテスト自動化するぜという方は、
こちらを検討してみる価値はあるのではと思います。
私も使ってみたら記事書こうと思います。多分。