Selenium + AI による Web テスト自動化: より高速なテスト設計、よりスマートなデバッグ、より信頼性の高い UI カバレッジ

Selenium + AI による Web テスト自動化: より高速なテスト設計、よりスマートなデバッグ、より信頼性の高い UI カバレッジ

Selenium + AI による Web テスト自動化: より高速なテスト設計、よりスマートなデバッグ、より信頼性の高い UI カバレッジ

導入

セレンはいくつかのファッショナブルな葬儀を生き延びました。数年ごとに誰かが、古典的なブラウザの自動化は脆弱すぎる、遅すぎる、古すぎる、セレクターに縛られすぎている、メンテナンスが煩わしい、したがって、より新しく、より輝かしく、カンファレンスの基調講演で登場する可能性が高いものに置き換えられる準備ができていると発表します。それでも、チームは依然として Selenium を使用しています。その理由は 1 つあります。それは、実際の製品における実際の配信の問題を解決し続けているからです。

AIの時代ではそれはさらに当てはまります。

AI によって Selenium が時代遅れになるわけではありません。 Selenium は、適切な場所に適用するとさらに便利になります。ブラウザードライバーは、これまでと同じように、ページを開いて、クリックし、状態が変わるのを待ち、結果を読み取り、UI が嘘をついたときに大声で失敗します。変化するのは、そのループの周りのすべてです。 AI は、チームがテストの最初のドラフトをより迅速に作成し、要件をカバレッジのアイデアに変換し、よりインテリジェントにロケーターを生成および修復し、障害を要約し、欠落しているアサーションを提案し、通常はテスト スイートからエネルギーを消耗する退屈なメンテナンス作業を削減するのに役立ちます。

それがこの記事の重要な考え方です。 Selenium と AI は競合相手ではありません。それらは異なる層に位置します。 Selenium は引き続き実行エンジンです。 AI は、計画、オーサリング、トリアージ、および制御された治癒に関する加速レイヤーになります。

この分離をきれいに保つと、その組み合わせは真に生産的になります。曖昧にしすぎて、モデルが魔法のように「QA を所有する」ことを期待すると、より良いパッケージ化が混乱を招くことになります。

この記事では、組み合わせがどのように機能するか、AI が最も役立つ場所、どのツールが仕事に適しているか、うまく解決できるケースの種類、限界はどこにあるのか、初心者が実際のコードを使用して小規模ながら立派な AI 支援 Selenium ワークフローを構築する方法について説明します。

AI が Selenium を実際に高速化する場所

最初の有益な真実は、AI はブラウザ自体を高速化しないということです。モデルが近くにあるため、Chrome の起動が速くなりません。誰かが LLM API 呼び出しを追加したため、クリックが早く到達しません。ネットワーク応答を待機中は、依然としてネットワーク応答を待機しています。

実際の高速化は、ブラウザ周りのエンジニアリング ループで発生します。

最初のループはテスト設計です。チームは多くの場合、最終的なアサーションの作成よりも、要件、サポート チケット、バグ レポートを具体的なテスト シナリオに変換することに多くの時間を費やします。 AI は、製品の動作に関する段落をシナリオ、エッジ ケース、ネガティブ パスの初稿に変えるのが得意です。優秀なエンジニアは依然としてその出力をレビューして再形成しますが、白紙のページははるかに早く消えます。

2 番目のループはロケーターのオーサリングと修復です。フロントエンド チームはクラスの名前を変更し、コンテナを移動し、ボタンを 3 つの新しいレイヤーでラップし、自動化スイートを昨日のセレクターで雨の中に放置します。 AI は、DOM フラグメントや「プライマリ チェックアウト ボタン」や「アカウント作成フォーム内の電子メール入力」などのインテント記述から候補セレクターを生成するのに役立ちます。レビュー ゲートと併用すると、制御を放棄することなく時間を節約できます。

3 番目のループは障害のトリアージです。不安定なテストは失敗し、チームは 5 つの質問に素早く答えなければなりません。 UIが変わったのかな?環境が遅くなったのでしょうか?セレクターが古いのでしょうか?その主張は間違っているのでしょうか?本当に商品が壊れているのでしょうか? AI は、ログ、スクリーンショット、DOM スニペット、スタック トレースを短い技術仮説リストに変換するのに驚くほど役立ちます。ここで、実際に多くの時間の節約が見られます。

4 番目のループはカバレッジの拡張です。安定したハッピー パス テストが存在すると、AI は隣接するカバレッジ (空の状態、無効な資格情報、無効なボタン、ロケールの変動、権限の違い、タイムアウト処理、複数ステップのロールバック動作) を提案するのに役立ちます。これは、チームの職務範囲が広く、人間の注意力が限られている場合に特に役立ちます。

5 番目のループはレポートです。生のテストレポートは多くの場合、正確であると同時に役に立ちません。 AI は、障害クラスターのビジネス上の意味を要約し、類似したエラーをグループ化し、どの障害が同じ根本原因を共有している可能性があるかをチームに伝えることができます。それはエンジニアリング診断に代わるものではありません。診断をより良いところから開始できるようになります。

AI によって Selenium が高速になるのかと尋ねられると、正直な答えは次のとおりです。AI によってブラウザが高速になることはめったにありませんが、ブラウザを使用するチームの速度が大幅に向上することはよくあります。

Selenium と AI がうまく連携する理由

Selenium は、実際のブラウザと実際の DOM に対して動作を検証する必要がある場合に最も強力です。 AI は、あいまいさ、繰り返し、または言語を多用した入力によって人間の速度が低下する場合に最も威力を発揮します。

この組み合わせは、最初に思ったよりも健全です。

Selenium は決定論を提供します。これにより、明示的な待機、要素の状態チェック、ナビゲーション コントロール、スクリーンショット、ブラウザ コンソール アクセス、Selenium Grid を介したリモート実行が可能になります。それは厳格で、頑固で、文字通りです。これらはテスト実行者の優れた資質です。

AI は弾力性を提供します。乱雑な要件、ノイズの多いログ、不十分に記述されたバグ チケット、不安定なロケーターの説明、不完全なテストの初稿を解釈するのに役立ちます。これらはすべて、純粋な決定論が高価になる領域です。

言い換えれば、Selenium は、パスを正確に実行する必要がある場合に優れています。 AI は、最初にパスを理解、拡張、または修復する必要がある場合に優れています。

これが、最も有用なアーキテクチャが通常「AI が Selenium に置き換わる」ことではない理由です。それは、「AIが準備・支援・診断し、Seleniumが実行・検証する」です。

この分離をスタックに組み込むと、結合されたシステムの信頼がはるかに容易になります。

この組み合わせが最もよく解決するケース

一部のユースケースでは、他のユースケースよりも AI 支援 Selenium の恩恵を受けることができます。

有力なケースの 1 つは、頻繁に外観が変更される大規模な UI サーフェスです。製品チームは、動作のリファクタリングよりもレイアウトのリファクタリングの方が速いことがよくあります。チェックアウトはまだチェックアウトされています。ログインは引き続きログインします。テーブルは引き続きフィルタリングされます。しかし、DOM は脆弱なテストを中断するほどに変化します。 AI 支援によるロケーター修復、DOM 解釈、よりスマートなセレクター生成により、ここでのメンテナンス時間を大幅に節約できます。

もう 1 つの良い例は、QA 言語ではなく製品言語から構築された回帰カバレッジです。創設者、PM、サポート エンジニア、営業チームは人間の言葉でバグを説明します。 「カートに戻ると割引が消えてしまうことがあります。」 「ユーザーはタブを切り替えるとオンボーディングを完了できません。」 「役割の変化は完全には伝わりません。」 AI は、言語を多用したレポートを、人間が毎回ゼロから始めるよりも速く、より鮮明な Selenium シナリオに変換できます。

3 番目の強力なケースは、騒がしいスイートでの失敗のトリアージです。夜間スイートの 12 か所で障害が発生した場合、AI レイヤーはそれらの障害をクラスタリングし、そのトレースを検査し、スクリーンショットを比較し、どの 3 つが同じ製品の問題である可能性が高いかを示唆できます。これにより、朝のトリアージのコストが削減されます。

4 番目の良いケースは、フォームと権限に関する対象範囲の拡大です。これらの領域では、必須フィールド、無効な組み合わせ、サーバー側のエラー状態、役割ベースの可視性、ロケール形式、珍しいが高価なビジネス パスなど、数十のバリエーションが生成されることがよくあります。 AI はこれらの組み合わせを列挙し、チームが明らかな盲点を回避できるように支援します。

5 番目のケースは、プレッシャーにさらされたプロトタイプの自動化です。概念実証を構築したり、リスクのある製品パスを検証したりするチームは、システム全体がエレガントになる前にテスト カバレッジが必要になることがよくあります。 AI は、最初の有用な自動化レイヤーをより迅速に導入するのに役立ちますが、Selenium は引き続き実際のブラウザーの動作を処理します。

UI が小さく、安定していて、簡単なテストですでに十分にカバーされている場合、この組み合わせはあまり魅力的ではありません。また、チームが判断を完全に外部委託したい場合にも、あまり魅力的ではありません。 AI 支援による自動化は、チームがエンジニアリングの所有権を依然として望んでいる場合にうまく機能します。チームが魔法を望んでいる場合、それはうまく機能しません。

通常重要なツール

ツール スタックは特殊なものである必要はありません。

基本的には、Selenium 4 と、pytestJUnitTestNG などの規律あるテスト ハーネスが依然として必要です。分散実行には、Selenium Grid が引き続き最適です。レポートの場合、チームは Allure または同様の構造の HTML レポート レイヤーを使用するとうまくいきます。ブラウザー ドライバーのセットアップの場合、webdriver-manager または同等の環境制御により、セットアップが予測可能に保たれます。

AI レイヤーは軽量にすることができます。多くのチームでは、これは、制約付きプロンプトを LLM API またはローカル モデルに送信し、構造化された JSON 応答が返されることを期待する単なる薄い内部ヘルパーです。特にロケーター修復の場合、Healenium は Selenium エコシステムの既知のオプションであり、独自の狭いバージョンを構築する場合でも研究するのに役立ちます。主な教訓は「奇跡のツールをインストールする」ことではありません。主な教訓は、「システムに修復を提案させる場合は、システムに修復の説明を強制し、プロモーションを人間が制御できるようにすること」です。

サポート資産も重要です。 AI を利用した優れた Selenium セットアップでは、次のものが保存されることがよくあります。

  • 障害点周辺の DOM スナップショット
  • スクリーンショット
  • ブラウザコンソールのログ
  • ネットワークタイミングのヒント
  • 各重要なステップに対するユーザーの意図を明確にテキストで説明

最後の項目は過小評価されています。失敗したステップが単に find_element(By.CSS_SELECTOR, ".btn-42") であるだけでなく、「購入を完了する主ボタン」のような意図が含まれている場合、AI はより適切に機能します。インテントは、無効なセレクターを回復可能な命令に変換します。

正直さを保つ実用的なアーキテクチャ

最も健全なアーキテクチャは、良い意味で退屈です。

Selenium テストは、ページ オブジェクトまたはコンポーネント、明示的な待機、安定したアサーション、再利用可能なヘルパー、明確なテスト データ、適切な命名など、通常の規律あるスタイルで作成します。次に、その安定したコアの周りに、3 か所に狭い AI 支援を追加します。

まずはシナリオ立案です。要件またはバグレポートが与えられると、AI は候補シナリオを生成します。これらはすぐに実行されるわけではありません。彼らは、彼らを承認したり、再形成したりする人間のところに行きます。

2 位は ロケーターの提案 です。セレクターが失敗すると、システムは DOM フラグメントと人間が判読できるステップ インテントをモデルに送信し、候補セレクターの短いリストを要求できます。結果はレビューされ、記録され、必要に応じて受け入れられます。

3位は失敗まとめです。モデルはテストのメタデータ、ログ、トレース、スクリーンショットを参照し、曖昧な段落ではなく構造化された仮説リストを返します。

パターンに注目してください。 AI は不確実性の境界で使用されます。 Selenium は実行時点に留まります。

それが維持する価値のあるアーキテクチャです。

コード: クリーンな Selenium ベースライン

AI を追加する前に、ベースラインを示す価値があります。基礎となる Selenium コードがカオスである場合、AI レイヤーはカオスを高速化するだけです。

以下は、明示的な待機とページ オブジェクト規律を備えたログイン フローの小さな pytest の例です。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class LoginPage:
    def __init__(self, driver, base_url: str):
        self.driver = driver
        self.base_url = base_url.rstrip("/")
        self.wait = WebDriverWait(driver, 10)

    def open(self) -> None:
        self.driver.get(f"{self.base_url}/login")

    def fill_email(self, email: str) -> None:
        field = self.wait.until(
            EC.visibility_of_element_located((By.NAME, "email"))
        )
        field.clear()
        field.send_keys(email)

    def fill_password(self, password: str) -> None:
        field = self.wait.until(
            EC.visibility_of_element_located((By.NAME, "password"))
        )
        field.clear()
        field.send_keys(password)

    def submit(self) -> None:
        button = self.wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))
        )
        button.click()

    def success_banner_text(self) -> str:
        banner = self.wait.until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-test='login-success']"))
        )
        return banner.text


def test_login_happy_path(driver, base_url):
    page = LoginPage(driver, base_url)
    page.open()
    page.fill_email("user@example.com")
    page.fill_password("correct-horse-battery-staple")
    page.submit()

    assert "Welcome back" in page.success_banner_text()

ここには魅力的なものは何もありません、そしてそれがまさに重要なのです。 AI 支援による自動化は、信頼性の高い自動化から始まります。

コード: レビュー ゲートを使用した AI 支援ロケーター修復

ここで、注意深く制限された AI ヘルパーを追加します。目標は、モデルが暗闇の中で黙ってスイートを書き直せるようにすることではありません。目的は、既知のステップが失敗したときに候補セレクターを提案できるようにすることです。

以下の関数は、人間が判読できるステップ インテントと DOM スニペットを取得し、AI レイヤーに構造化されたセレクターの候補を要求し、それらを検証して、ブラウザーで実際に解決される最初のセレクターを返します。

from __future__ import annotations

from dataclasses import dataclass
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from typing import Iterable
import json


@dataclass
class SelectorSuggestion:
    css: str
    reason: str


def call_llm_for_selectors(step_intent: str, dom_excerpt: str) -> list[SelectorSuggestion]:
    """
    Replace this stub with your chosen provider.
    The only contract that matters is a strict JSON response:
    {
      "suggestions": [
        {"css": "button[data-test='checkout']", "reason": "stable data attribute"},
        {"css": "form button[type='submit']", "reason": "submit button inside target form"}
      ]
    }
    """
    fake_response = {
        "suggestions": [
            {
                "css": "[data-test='checkout-submit']",
                "reason": "Most stable explicit test selector"
            },
            {
                "css": "button[type='submit']",
                "reason": "Generic submit fallback"
            }
        ]
    }

    payload = json.loads(json.dumps(fake_response))
    return [SelectorSuggestion(**item) for item in payload["suggestions"]]


def validate_selector(driver, css: str) -> bool:
    try:
        driver.find_element(By.CSS_SELECTOR, css)
        return True
    except NoSuchElementException:
        return False


def resolve_selector_with_ai(driver, step_intent: str, dom_excerpt: str) -> SelectorSuggestion | None:
    for suggestion in call_llm_for_selectors(step_intent, dom_excerpt):
        if validate_selector(driver, suggestion.css):
            return suggestion
    return None

クリティカル クリックの周囲でこれを使用する方法は次のとおりです。

from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException


def click_checkout(driver, dom_excerpt: str) -> None:
    primary_selector = "[data-test='checkout-button']"

    try:
        driver.find_element(By.CSS_SELECTOR, primary_selector).click()
        return
    except NoSuchElementException:
        pass

    suggestion = resolve_selector_with_ai(
        driver=driver,
        step_intent="Primary button that completes checkout",
        dom_excerpt=dom_excerpt,
    )

    if suggestion is None:
        raise AssertionError("Checkout button not found and no valid AI repair was produced.")

    # Review gate: log the repair before you accept it permanently.
    print(f"[AI selector repair] {suggestion.css} :: {suggestion.reason}")
    driver.find_element(By.CSS_SELECTOR, suggestion.css).click()

ここが重要な部分です。AI の提案は、目に見えない突然変異エンジンとしてではなく、回復メカニズムとして使用されます。候補者を生み出します。ブラウザは候補を検証します。チームは理由を記録します。人間は後で、修復されたセレクターをスイート内の新しい正規セレクターにするかどうかを決定できます。

このパターンにより、コントロールを放棄することなくスピードが得られます。

コード: AI を使用してテストを作成する前にシナリオを拡張する

もう 1 つの便利なアプリケーションは、特徴言語をシナリオ候補に変換することです。

空白のドキュメントから始めるのではなく、AI に短い機能の概要を与え、構造化されたケースを要求します。その後、承認されたケースのみが実際の Selenium テストになります。

import json


def generate_case_matrix(feature_description: str) -> list[dict]:
    """
    In production this would call an LLM and demand a strict schema.
    We keep the example deterministic here.
    """
    response = {
        "cases": [
            {
                "name": "valid_login",
                "goal": "User signs in with valid credentials",
                "priority": "high"
            },
            {
                "name": "locked_account",
                "goal": "User sees the correct message for a locked account",
                "priority": "high"
            },
            {
                "name": "password_reset_link",
                "goal": "User can navigate from login to password reset",
                "priority": "medium"
            },
            {
                "name": "throttle_after_many_attempts",
                "goal": "UI communicates rate limiting after repeated failures",
                "priority": "medium"
            }
        ]
    }

    return response["cases"]


feature_text = (
    "The login page allows email and password sign-in, reports locked accounts, "
    "links to password reset, and throttles repeated invalid attempts."
)

for case in generate_case_matrix(feature_text):
    print(f"{case['priority'].upper()} :: {case['name']} :: {case['goal']}")

これは、テスト自動化で AI を使用する方法の中で最も議論の余地のない方法の 1 つです。モデルはブラウザに触れていません。それはチームがより幅広く、より速く考えるのに役立ちます。

チームが通常どの程度のアクセラレーションを参照しているか

これは人々が過度に単純化しがちな部分です。

AI が 1 つのクリーンで普遍的な乗数を提供することはほとんどありません。実際の利益は、スイートの成熟度、製品ドメインの明確さ、UI の安定性、チームのレビュー規律、そして AI が本当のボトルネックを解決しているのか、それとも誰かが「AI テスト戦略」を望んでいるために単にプロセスに固定されているのかによって決まります。

実際には、通常、最大の利点は次の点に現れます。

  • 初稿シナリオの生成
  • 繰り返しのロケーター作業
  • 不安定な失敗のトリアージ
  • 騒がしいレポートを要約する
  • 製品言語のバグを自動化候補に変える

すでに安定しており、十分にファクタリングされているスイートでは多くの場合、利益は控えめですが、UI が頻繁に変更され、自動化されていない動作のバックログが大きい、乱雑な中成長環境でははるかに大きくなります。

これをわかりやすく説明すると、次のようになります。AI は通常、マシン時間を節約する前に エンジニアリングの注意力を節約します。それを理解すると、期待は再び正常になります。

尊重すべき制限

AI 支援の Selenium は、チームが決定論的であるべきものを忘れてしまうと危険になります。

アサーションは明確かつ明確に保つ必要があります。モデルは、「良い」という意味を事後的に考え出すべきではありません。要素の相互作用は観察可能かつ再現可能でなければなりません。クリティカル パスのテスト データは、むやみに推測しないでください。また、修復システムは、レビューせずにセレクターを大量に書き換えるべきではありません。

さらに人間的な限界もあります。 AI は、妥当なテストのアイデアを非常に迅速に大量に生成できます。もっともらしいことと重要なことは同じではありません。弱いチームは、生産的であるように見える「報道」に溺れ、実際のビジネスリスクを見逃してしまう可能性があります。強力なチームは AI を使用して機械的な労力を軽減し、重要なことに対する判断力を維持します。

それが加速と劇場の間の本当の境界線です。

実用的なスターター スタック

これを規律ある方法で構築したい場合は、通常は小さなスターター スタックで十分です。

  • セレン 4
  • pytest
  • webdriver-manager または CI での安定したドライバーのプロビジョニング
  • Allure または同等のレポート レイヤー
  • 厳密な JSON を返す小さな内部 AI ヘルパー
  • 失敗したステップの保存された DOM スニペットとスクリーンショット
  • ロケーターの修復とテストケースのプロモーションのための手動レビュー ゲート

そのスタックは、それを中心に大規模なフレームワークを構築する前に、その価値を証明するのに十分です。

初心者向けの実践的なタスク

Selenium と AI 支援によるテスト自動化を初めて使用する場合は、大規模なコマース フローから始めないでください。小さくて教えやすい目標から始めましょう。

デモ サイトまたは内部の重要ではない環境を使用して、次の操作を実行します。

  1. ログインまたは検索用の安定した Selenium テストを 1 つ構築します。
  2. セレクターをテスト内に直接置くのではなく、ページ オブジェクトを記述します。
  3. 明示的な待機を追加して、テストを 5 回連続で確実にパスさせます。
  4. テストが失敗した場合は、ページの HTML を保存します。
  5. 失敗したステップの説明と保存された DOM の抜粋を受け入れ、2 つまたは 3 つの候補 CSS セレクターを返すヘルパーを追加します。
  6. これらのセレクターを使用する前に、ブラウザーでセレクターを検証してください。
  7. 選択した修復をログに記録し、それを新しい公式ロケーターにするかどうかを手動で決定します。

あなたの仕事は「AIにQAをやらせる」ことではありません。あなたの仕事は、AI が信頼性を損なうことなく摩擦をどこまで軽減できるかを確認することです。

具体的なチャレンジが必要な場合は、次のことを試してください。

初心者向けエクササイズ

次のような自動化フローを構築します。

  • ログインページを開きます。
  • サインインを試みます。
  • 元の送信セレクターが意図的に破壊されたことを検出します。
  • AI 提案スタブを使用して代替セレクターを見つけます。
  • クリックが完了すると、
  • そして、修復の理由をテスト出力に記録します。

次に、次の質問に答えてください。

  • 修理により時間は節約できましたか?
  • 提案されたセレクターは実際に優れたものでしたか?
  • レビューなしで信用しますか?
  • フローのどの部分が決定的だと感じられ、どの部分が確率的だと感じましたか?

これらの回答は、「QA における AI の将来」に関する 10 件以上の漠然としたブログ投稿を教えてくれます。

結論

Selenium と AI は、それぞれが本来得意とする種類の作業を実行できる場合にうまく連携します。

Selenium は、実行、待機、アサーション、ブラウザーの動作、および再現可能な検証を所有し続ける必要があります。 AI は、草案、拡張、解釈、修復、要約を支援する必要があります。この部門はシステムを有用な状態に保ち、チームを誠実に保ちます。

その見返りは本物です。最初の草稿をより速く書くことができます。 UI のドリフトからより早く回復します。失敗の優先順位付けを迅速に行うことができます。よりインテリジェントに対象範囲を拡大します。そして、モデルが QA リーダーになったかのように振る舞うことはありません。

それがこの物語の成熟版です。魔法の自動化ではありません。エンジニアリングの活用が向上します。

そして、実際のソフトウェア チームでは、レバレッジが仕事を動かすのです。

Yevhen R.

Yevhen R. – ソフトウェアエンジニア兼AI研究者

ブログに戻る

接触

会話を始める

明確な線が数本あれば十分です。システム、プレッシャー、そして妨げられた決断について説明してください。 または直接書いてください midgard@stofu.io.

01 What the system does
02 What hurts now
03 What decision is blocked
04 Optional: logs, specs, traces, diffs
0 / 10000