Help us understand the problem. What is going on with this article?

ちゃんと動いていたSeleniumがたまに失敗するケースまとめ

More than 5 years have passed since last update.

この記事は、 Selenium Advent Calendar 2013 の21日目の記事です。

Seleniumを日々運用していると何回かに1回失敗するようなエラーに遭遇することがよくあります。
今回はそんな気まぐれエラーについて、これまで経験したパターンの主なものをまとめてみました。
また、参考までにそのパターン対して行った対策の一例をあげています。

指定したセレクタが一意になっていない

class属性で指定している場合はよくあるパターン。動的なページは条件によって同じ指定の要素が複数表示されるケースがあり、時と場合によってエラーになる。

対策例

なるべく一意になる指定をする。idを使う、inputのnameを使うなど。
Selenium Advent Calendar 2013 12/1の記事がとても参考になります。
Selenium の locator とうまくつきあうための話

イベントがバインドされてない

クリック動作をテストする場合にクリックする要素にjsのイベントがバインドされる前にSeleniumがテストを実行してしまう。クリックは実行されるがイベントが実行されないので想定通りのテストが行えない。

対策例

バインドされるまでwaitを入れる。例えばある要素がロードされた時にイベントがバンドされていると判定できる場合は、その要素に対してwaitを入れる。最終手段は秒数を指定してsleepさせる。

バインドされている要素と違う要素をクリックしている

例えば以下のようなアイコンを選択させるhtmlがあってそれをクリックするコードを作った場合、js側のclickイベントをバインドしている要素とSeleniumのクリックする要素が合っていないとクリックが反応しないことがある。

<div class="icon tooltip-top">
    <a href="#" >
        <i class="icon-menu"></i>
    </a>
</div>

例)プログラムはa要素にイベントをバインドしているが、Selenium IDEではi要素をclickするコードが生成される。

対策例

これはアプリ側の実装に合わせるしかない。
Selenium IDEを使うとそのような空気を読んだコードは作ってくれない。
運用しやすいコードに仕上げるためにはある程度アプリ側の知識が必要。

要素は存在するが見えてない

DOM上には存在するが実際に表示される前にSeleniumがテストを実行してしまう。あらかじめDOM上に存在させておいてCSSのdisplay属性の指定で表示/非表示を切り替えるようなプログラムを組んだ場合、DOM上の要素を正しく指定してwaitしているつもりでも非表示の状態でテストが実行される場合がある。

対策例

wait.until()に指定するExpectedConditionsのメソッドを正しく使う。
例えばvisibilityOfElementLocated()は表示されるまで待ってくれるが、presenceOfElementLocated()は表示/非表示にかかわらずDOM要素の存在だけしか待たない。

visibilityOfElementLocatedは要素が表示(hightまたはwidthが0より大)になるまで待つ
wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
presenceOfElementLocatedはDOM要素として存在していればOKとなる
wait.until(ExpectedConditions.presenceOfElementLocated(locator));

ドキュメントを参考にして正しくwaitを入れる。

ExpectedConditionsのJavaDoc(英文)

日本語でまとめてくださっているかたがいます。

チラシの裏的備忘録 | Wait.until()で指定できる状態の種類

アニメーションが待てていない

メッセージがフェードインするような処理の場合、そのままSeleniumのテストを実行するとフェードインが終わる前にテストが先に進んでエラーになる。

対策例

メッセージなどの画面に変化が現れる要素があればまずはその要素に対してwaitを入れる。
ただし、前出のvisibilityOfElementLocatedはhightやwidthが0より大きくなるまでしか待たないのでDOM構成やアニメーションのパターンによってはwaitが終わった時点ではまだ想定通りの表示に達していない場合もある。

例)span要素が表示されるまでwaitさせたが、実際にはそのあとゆっくり文字がフェードインするため、wait終了時点ではSeleniumが文字を検出できない

最終手段としてはアプリの実装に合わせてアニメーションにかかる時間のsleepを入れる。

まとめ

Seleniumの運用で最も厄介なのは、アプリの不具合検知以外の原因でエラーになるケースが多々あり、しかも毎回エラーになるのではなく何回かに1回エラーになる現象が起こることです。ローカル環境では正常に動いたのにJenkinsからリモートで実行するとうまく動かなくなるようなケースもよくあります。この現象の原因調査に労力をかけすぎるのは不毛なので、1つ1つベストなケースを探るのではなくいくつかのパターンに応じた対策をあらかじめ決めておいて、まずは深く考えずにいずれかの対策を採用して様子を見るような進め方も運用を続けていくための知恵かもしれません。

一方で、このような何回かに1回しか起こらないエラーでも、ある環境下で正しく動かないのであればそれは不具合という見方もあります。エラーの原因を探ってみると無駄な処理や効率の悪い処理に気づくこともあります。結局は人間が判断するしかないのですが、そのために必要な知識やノウハウをためておくことがSeleniumを賢く運用していくために重要なのではないかと思います。

まだまだ様々なパターンがあると思いますのでノウハウが溜まってきたら続編を書きたいと思います。こんなケースもよくあるよという事例があれば教えてください。

radiocat
Web系技術とAndroidアプリ開発が中心。スクラムマスターもやってます。 よろしくお願いします。
http://radiocat.hatenablog.com/
rakus
「IT技術で中小企業を強くします!」というミッションを掲げ、中小企業の業務効率化に貢献する複数のクラウドサービスを提供しているIT企業です。「楽楽精算」「メールディーラー」など、国内トップシェアを誇る複数のサービスを開発し、累計導入社数は5万社を超えています。次の時代の"楽"を創るための、まだ見ぬサービスや機能を生み出す取り組みは、今日も続いています。
https://www.rakus.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした