明示的待機(Explicit Wait)と Expected Conditions

1. 明示的待機(Explicit Wait)の概要

  • 目的
    動的に変化する DOM に対し、「特定の条件が満たされるまで」処理を一時停止し、安定したテスト/自動操作を実現する。単純な time.sleep() とは異なり、条件が満たされ次第ただちに復帰するため、待機時間のムダを抑えられる。

  • 仕組み

    1. 待機管理クラス WebDriverWait(Python/Java)に 最大待機時間ポーリング間隔 を与える。

    2. Expected Conditions(条件オブジェクト/関数)を渡し、その条件が True を返すまでリトライ。

    3. タイムアウト到達で TimeoutException を送出。


2. WebDriverWait の基本構文

言語 インポート 生成 実行例
Python (Selenium 4) python from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By python wait = WebDriverWait(driver, timeout=10, poll_frequency=0.5) python element = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
Java (Selenium 4) java import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.By; java WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); java WebElement element = wait.until( ExpectedConditions.elementToBeClickable(By.id("submit")));

ポーリング間隔(既定 500 ms)は過度な DOM アクセスを防ぐ調整弁。試行ごとに NoSuchElementException など一部例外を自動で無視する点もポイント。


3. Expected Conditions(代表例と用途)

カテゴリ 条件メソッド 主な用途
要素の存在・可視性 presence_of_element_located / visibility_of_element_located DOM に挿入されるまで待機/ユーザー操作可能になるまで待機
クリック可能 element_to_be_clickable ボタン・リンクがクリック可能状態になるのを待機
テキスト/属性 text_to_be_present_in_element / attribute_to_be SPA の動的更新でテキストや属性が変わるまで待機
複数要素 presence_of_all_elements_located リストやテーブル行が一定数そろうまで待機
アラート alert_is_present JavaScript alert/confirm/prompt が出現するまで待機
非表示/消滅 invisibility_of_element / staleness_of ローディングスピナーが消える、DOM が張り替わるのを検知
フレーム/ウィンドウ frame_to_be_available_and_switch_to_it / number_of_windows_to_be iframe 切り替えや新規タブが開くまで待機

カスタム条件
WebDriverWait.until(lambda driver: driver.execute_script("return document.readyState") == "complete") のように、ラムダや独自クラスで柔軟に定義できる。


4. 実践パターン

a. ページ読み込み完了+特定要素がクリック可能になるまで

python
wait = WebDriverWait(driver, 15) wait.until(lambda d: d.execute_script("return document.readyState") == "complete") wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".confirm")))

b. Ajax 更新で行数が変わるテーブルを監視

java
By rows = By.cssSelector("table#orders tbody tr"); int before = driver.findElements(rows).size(); new WebDriverWait(driver, Duration.ofSeconds(20)) .until(ExpectedConditions.numberOfElementsToBeMoreThan(rows, before));

5. ベストプラクティス & 注意点

  1. 暗黙的待機と併用しない
    両方を設定すると待機時間が加算/競合し、思わぬ長時間ブロックや TimeoutException を招く。テストごとに「どちらか一方」に統一する。

  2. 適切な最大待機時間の設定

    • 通信品質やサーバー性能を考慮し、現実的な上限を決める(一般的に 5–20 秒)。

    • フレーク(不安定)テストを防ぐため、実アプリの SLA + α を基準に。

  3. ポーリング間隔のチューニング
    高負荷ページでは 1 秒程度に伸ばし、CPU 使用率と安定性を両立。

  4. 例外のホワイトリスト
    既定無視リスト以外の例外(ElementClickInterceptedException など)が頻発する場合、wait.until() に try–except を追加して制御。

  5. FluentWait の活用(Java / C#)

    • 条件ごとに 待機時間・ポーリング・無視例外 を細かく指定可能。

    • withTimeoutpollingEveryignoring() でチェイン。

  6. ページオブジェクトパターンとの統合
    OO 設計で要素取得メソッドに待機ロジックを内包させると、テストコードが簡潔かつ再利用可能に。

  7. ログ出力とメトリクス
    タイムアウト発生時に URL・条件内容・残り時間をロギングし、ボトルネック分析 に備える。


6. まとめ

  • 明示的待機は「いつ終わるかわからない非同期動作」に対して最も信頼できる同期手段。

  • Expected Conditionsを使うことで「要素の可視化」「テキスト更新」など UI 状態を高粒度に捉えられる。

  • ただし設計ルール(暗黙的待機との排他・適切なタイムアウト・例外管理)を守らないと、テストの不安定さや実行時間の増大につながる。
    これらの指針を守り、ページ特性に合わせてチューニングすることで堅牢かつ高速な Selenium スクリプトを構築できる。

ChatGPT4o 生成日:2025/06/21