また「element not found」? セレクターとロケーターが壊れたときのテスト方法

「element not found」が出たら? セレクターとロケーターが壊れる理由 (動的 ID、Shadow DOM、iframe、canvas) と、保守すべきロケーターなしでテストする方法。

執筆: Ait Nohaila (事業開発担当) 読了 14 分

「element not found」とは、テストがロケーターで要素を探し、時間内に何も一致しなかったという意味です。解決策がより良いロケーターであることはまれで、本当の解決策はユーザーに見えるものを確認するテストです。

QA エンジニアなら誰でも知っている朝があります: 赤いテストが 20 件、本物のバグは 1 件もない朝です。開発者がクラス名を変え、デザインチームがバナーを動かし、フレームワークの更新が ID を変えました。この記事では、ロケーターが壊れる理由、エラーが出たときの直し方、いつもの対策の限界、そして保守すべきセレクターなしでテストする方法を説明します。

「element not found」とは何か

Definition

「element not found」エラーとは、テストがロケーターで要素を要求し、タイムアウトまでにページ上の何も一致しなかったという意味です。ロケーターはセレクターとも呼ばれ、テストが要素を指すための住所で、ID、CSS セレクター、XPath、ロールと名前、テキストなどがあります。Selenium は NoSuchElementException を投げ、Playwright は操作をタイムアウトで終え、ほかのフレームワークにもそれぞれの呼び名があります。最後に伝えることはいつも同じで、ユーザーが見失ったかどうかに関係なく、テストが要素を見失ったということです。

Selenium 自身のトラブルシューティングのページは、考えられる原因を 3 つ挙げています: 探す場所が違う、探すタイミングが違う、あるいはコードを書いた後でロケーターが変わった、の 3 つです。ロケーターそのものの問題は最後の 1 つだけで、リリースのたびに増えていくのもこの原因です。

#save-8f3a2c

新しいビルドが別の ID を生成する

.btn-primary

リデザインでクラス名が変わる

text=Save

フランス語版では Enregistrer と表示される

//div[3]/form/button[2]

フォームの上にバナーが追加される

画面上

Save

ユーザーにとっては変化なし

ありふれた 4 つの変更で、4 つのロケーターが壊れます。ユーザーに見えるボタンは 4 つとも同じです。

セレクターとロケーターはなぜ壊れるのか

ロケーターは、アプリケーションがどう作られているかについての推測です。ユーザーに見えるものを変えずに作りだけを変える変更は、どれもロケーターを壊す可能性があります。

何が変わったかどのロケーターが壊れるかユーザーは気づいたか
生成された ID とクラス名フレームワークが書く ID やクラスで、ビルドやページ読み込みのたびに変わるものいいえ
リデザインやリファクタリングページの構造をたどる CSS の連鎖や XPath多くの場合いいえ
A/B テストテストが想定していなかったバリアントのあらゆるロケーターそのバリアントのユーザーだけ
翻訳表示テキストやアクセシブルネームによるロケーター翻訳が正しければいいえ
Shadow DOM と iframeコンポーネントやフレームの中に入れないロケーターいいえ
仮想化リストスクロールして表示されるまで描画されない行のロケーターいいえ
canvas、ゲーム、アクセシビリティツリーのないアプリすべてのロケーター: 中に指し示せるものが何もないいいえ

動的 ID と生成されたクラス名

多くのフレームワークは save-8f3a2c や css-1x7hq のような独自の ID やクラス名を書き出します。一意なので完璧なロケーターに見えますが、次のビルドで変わります。それに対して記録したテストは今日は合格し、次のデプロイの後、誰も触っていないページで失敗します。

リデザイン、リファクタリング、A/B テスト

.form > div:nth-child(3) button のような CSS セレクターや //div[3]/form/button[2] のような XPath は、ページの中の道順を表しています。フォームを新しいコンテナーで包む、上にバナーを追加する、2 つのフィールドを並べ替えるだけで、道順は別の場所につながります。A/B テストは同じことを意図的に行い、訪問者の半分はロケーターが想定していないページを受け取ります。

Playwright のドキュメントははっきり書いています: XPath と CSS セレクターは DOM 構造に結びつくことがあり、構造が変わると壊れることがある。

ローカライズとテキストベースのロケーター

テキスト、ラベル、アクセシブルネームによるロケーターはリデザインに耐えるので、推奨されています。しかし翻訳には耐えられません。Save という名前で見つけていたボタンは、フランス語版が Enregistrer と表示すると見つからなくなるため、ローカライズされた製品では言語ごとのロケーターかテスト ID が必要です。

Shadow DOM と iframe

iframe はページの中のページで、Web コンポーネントは内部の要素を shadow root に持っています。Selenium は最上位のドキュメントの要素しか認識しないため、コードで書いたテストにはまずフレームに入るよう指示する必要があり、そうしないと要素は存在しないと報告されます。XPath のように、コンポーネントの中にはまったく入れないロケーターもあります。

仮想化されたリストとグリッド

1 万行の表が速いのは、すべての行を描画しないからです。広く使われているデータグリッドの AG Grid は、画面に見えている部分だけを描画すると説明しており、上下に少しの予備の行を加えるだけです。500 行目は誰かがそこまでスクロールするまでページに存在しないので、ロケーターでは見つからず、人ならただスクロールするだけです。

「element not found」エラーの直し方

Selenium、Playwright、Cypress では、エラーを直すのはあなたの仕事で、リリースのたびに戻ってきます。GUI Test Studio には直すべきロケーターがありません。

起きたことコードで書くフレームワークGUI Test Studio
要素の表示が遅い適切な条件の待機を自分で書く各アサーションがタイムアウトまで自動で待つ
要素がフレームや shadow root の中にあるフレームやコンポーネントに入る処理を自分で書く画面に描かれている場所で要素が見つかる
リデザインで ID や構造が変わったロケーターを書き直す。多くのテストにまたがることも多い書き直しは不要: 別の手がかりか、要素の画像が見つける
要素が意図して変更されたテストコードを編集するレポートでワンクリックすれば新しい見た目を採用できる

GUI Test Studio のテストが要素で止まったときは、次の 5 つの手順で解決でき、コードは一切不要です。

  1. 1

    実行の信頼度レポートを開く

    レポートは実行のたびに最初の失敗の箇所で開きます。アサーションがあきらめた瞬間の画面の横に期待画像を表示するので、要素がなかったのか、隠れていたのか、別の場所にあったのかがわかります。

  2. 2

    実行の開始地点を確認する

    テストは、その録画を始めた画面から始まります。アプリが別のページにあったり別のデータを持っていたりしたら、元の状態に戻してテストを実行し直してください。

  3. 3

    要素が大きく移動したら検索範囲を広げる

    アサーションの検索範囲で何も見つからないと、検索は自動で画面全体に広がります。要素が今後ずっと新しい場所にあるなら、レポートで検索範囲を広げるをクリックし、GUI Test Studio で新しい範囲を設定してください。

  4. 4

    意図した変更を採用する

    デザインが変わって要素の見た目が違うなら、信頼度レポートで実際の画像を期待画像として採用をクリックして保存します。編集するコードはなく、テストは最新になります。

  5. 5

    要素が本当に消えたならバグを報告する

    要素がなくなっていれば、テストは役目を果たしました。バグレポートをクリックすると、画像を添付した PDF または Jira の課題として登録できます。

CSS、XPath、ロール、テスト ID: どのロケーターにも弱点がある

コードでテストを書くチームは、触れる要素ごとにロケーターを選びます。どの種類も、それぞれのかたちで壊れます。

ロケーター例壊れるとき耐えられる変更
生成された ID やクラス#save-8f3a2c次のビルドほぼ何もない
CSS セレクター.form button.primaryクラスや構造が変わったとき新しいテキストや翻訳
XPath//div[3]/form/button[2]上や周りに何かが追加されたとき新しいクラス
ロールとアクセシブルネームrole=button, name=Saveラベルが変わったり翻訳されたりしたときリデザインとリファクタリング
テスト IDdata-testid=save-order開発者が削除したり名前を変えたりしたときリデザイン、翻訳、リファクタリング
  • どの戦略もリスクをなくすのではなく、移しているだけです。ロールと名前は言葉に依存し、言葉は翻訳や文言の修正のたびに変わります。テスト ID は習慣に依存し、すべての開発者がすべてのコンポーネントで、製品がある限りずっと追加し、維持し、決して使い回さないことが前提です。CSS と XPath は構造に依存しますが、構造こそリファクタリングが変えるものです。

XPath と CSS セレクターのどちらがよいかは最もよくある質問ですが、見た目ほど重要ではありません。CSS は短くて読みやすく、XPath はページを上にたどったりテキストで探したりできます。どちらもページの作りを表しているので、壊れ方も同じです。

GUI Test Studio では誰もロケーターを選びません。次のセクションで示すとおり、録画したテストが要素ごとに複数の手がかりを自動で保持します。

自己修復型のテスト自動化は壊れたロケーターを直せるのか

自己修復ツールは、テストが合格している間に各要素の追加情報を保存します。メインのロケーターが一致しなくなると、その情報で要素を探して続行します。

自己修復は便利ですが、知っておくべき限界が 3 つあります。出発点はやはりロケーターなので、修復先となる要素がページにある必要があります。変更を合格に変えてしまうので、修復のたびに人が確認しなければ、本物の変更がその陰に隠れます。要素がまったくない場所、つまり canvas、ゲーム、リモート画面では役に立ちません。

どのロケーターも届かない場所: canvas、ゲーム、アクセシビリティツリーのないアプリ

ここまでの戦略はすべて、アプリケーションが自分の要素を説明していることを前提にしています。説明しないアプリケーションも多く、その場合は良いロケーターも悪いロケーターも書きようがありません。

アプリケーションロケーターが届く範囲
canvas、グラフ、地図、WebGL のシーン画像を 1 枚持つ要素が 1 つだけ
ゲームウィンドウが 1 つだけ: ゲームはメニューを自分で描画する
Web 版の Flutterアプリがアクセシビリティを有効にするまで何もない: Flutter はインターフェースを canvas に描画し、Web ではアクセシビリティが任意で有効化する設定になっている
Qt、Java Swing、Delphi などの独自描画のデスクトップアプリ各コントロールの描き方によって、わずかか、何もない
Citrix、リモートデスクトップ、仮想マシン自分のパソコン上のピクセルのウィンドウが 1 つだけ

Windows デスクトップアプリについては、アクセシビリティツリーのないアプリのための WinAppDriver の代替で、どのプログラムが自分を説明し、どれが説明しないかを紹介しています。

アプリケーションが説明するものしかテストが見られないなら、何も説明しないアプリケーションはテストできません。それでもユーザーにはすべてのボタンが見えています。

保守すべきセレクターのないテスト自動化

Windows でエンドツーエンドテストを自動化する GUI Test Studio は、別の道を取ります: 誰もセレクターを書かず、保守もしません。テストは自分で操作の流れを実行して記録するか、プロンプトで説明し、すべてのアサーションはユーザーに見えるものを対象にします。

アサーション確認すること
ビジュアルアサーション要素が画面上にあり、期待どおりの見た目であること: その画像を見つけて比較する
テキストアサーションテキストが画面上の、あるべき場所で読めること
動的テキストアサーション日付、金額、注文番号のように、値が何であれ正しい形をしていること
レイアウトアサーション要素どうしが、互いに対してあるべき位置にあること

各要素を見つけるために、GTS Engine + AI は 2 つの道筋を使います。まずアプリケーションに尋ね、Windows アプリがコントロールについて提供するアクセシビリティ情報や、Web ページ自身の要素を使います。アプリケーションが何も言わないときは、画面上で見た目から要素を見つけます。両方の道筋の詳細はGUI Test Studio が画面上の要素を見つける仕組みで説明しています。

Web ページでは: 1 つの要素へ複数の道筋

Web テストでは、GUI Test Studio は操作する各要素への道筋を複数、順位をつけて保存します: テスト ID、ID、ロールと名前、ラベル、プレースホルダー、テキスト、そして最後にページ内の位置です。フレームワークが生成したように見える ID は、人が読めるものすべての後ろ、リストの終わり近くに回されます。

Save ボタンへの道筋を順番に試す

  1. 1テスト IDdata-testid="save"リファクタリングで削除
  2. 2ロールと名前role=button · name=Save発見
  3. 3テキストSave不要
  4. 4ページ内の位置form > button:nth-of-type(2)不要
ある道筋が一致しなくなると、次の道筋が要素を見つけます。実行はどの道筋で見つけたか、どれが変わったかを記録し、アサーションはそれでも画面を確認します。

そのため、テスト ID が削除されてもクラス名が変わっても、テストは止まらず、次の道筋が要素を見つけます。同じ道筋で shadow root 内の要素にも届き、スマートフォン向けに生成したテストでは、リンクを隠しているメニューを開くこともできます。

この最後の点こそが、記録した 1 つの Web テストを Chrome、Edge、Firefox、エミュレートしたスマートフォンで実行できる理由で、1 回の記録からのクロスブラウザーテストで紹介しています。

デスクトップアプリでは: まずコントロール、次に画面

Windows アプリでは、ボタンに対して作ったアサーションは、アプリがそのボタンについて伝えた名前、種類、位置を保存します。実行のたびにエンジンはまず動作中のアプリにそのボタンを尋ね、アプリが示す枠の中でその画像を探します。同じボタンが複数ある場合は、記録したボタンがあった場所に最も近いものを選びます。

テキストアサーションは画面上の文字を読む前に要素が何と言っているかをアプリに尋ねるので、画面上で読みにくい言葉でも、アプリが実際に言っている内容と照合されます。

それ以外の場所では: 見た目で

ゲーム、canvas、Citrix セッション、アクセシビリティツリーのないプログラムは、アプリケーションに何も追加せずに見た目でテストします。アサーションは検索範囲の中で要素の画像を探し、テキストアサーションは画面上の文字を読みます。

例canvas 上のグラフ

ダッシュボードは売上グラフを canvas に描画するので、どのロケーターも棒や凡例には届きません。3 月の棒をクリックする操作を記録し、凡例のビジュアルアサーションを追加します。クリックは棒の画像を通して狙いを定め、凡例はユーザーに見えるとおりに確認されます。

要素が動いたり変わったりしたときに起きること

1 つのロケーターに依存しないテストでも、変化には対処しなければなりません。各段階で GUI Test Studio が行うことは次のとおりです。

尋ねる

アプリケーションが要素の場所を伝える

見る

または検索範囲の中で画像が見つかる

広げる

何もなければ画面全体へ

報告する

どこで見つかったか、その理由

  • 各段階は、それぞれ別の種類の変化に対応します。ウィンドウが動いた、レイアウトがずれた、リストがスクロールした場合は、アプリケーションが要素の今の場所を伝えるか、そこで画像が見つかります。要素が検索範囲から外れた場合は、そこで何も見つからないと検索が画面全体に広がり、信頼度レポートが範囲の外で見つかったことを、範囲を広げるリンクとともに伝えます。テキスト認識がうまく読めない言葉は、テキストアサーションがアプリケーションに要素の内容を尋ねます。最初のロケーターが壊れた Web 要素は次の道筋が見つけ、実行はどの道筋が変わったかを記録します。

クリックも要素についていきます: 各クリックは直前のアサーションを通して狙いを定めるので、ボタンが動けばクリックも一緒に動きます。各アサーションの設定方法はビジュアルアサーションとテキストアサーションをご覧ください。

それでも人の判断が必要なこと

どんな方法でも、すべての変更がただで済むわけではありません。人が判断するのは次のような場合です。

状況すべきこと
要素の見た目が意図的に変わったアサーションは期待と実際の画像を並べて表示して不合格になります。信頼度レポートで実際の画像を期待画像として採用をクリックし、保存してください。
画面サイズや拡大率が記録時と違う見た目によるアサーションは画像を比較するので、同じ画面サイズと拡大率で実行するか、それぞれにベースラインプロファイルを用意してください。
アプリが記録開始時と同じ状態から始まらないアプリケーションを記録開始時の状態に戻してください: 同じページ、同じデータ、同じ開いているウィンドウです。
A/B テストが別のバリアントを返すテスト環境でバリアントを固定するか、バリアントごとにベースラインプロファイルを用意してください。
要素が本当に消えたそれはバグです。テストは不合格になり、レポートには何がどこに期待されていたかが表示されます。

新しい見た目を採用するではワンクリックの更新を、不安定なテストと誤検知ではアサーションが無害なノイズと本物の変更をどう見分けるかを説明しています。

ロケーターに頼るアサーションが見ないまま通してしまう見た目のバグについては、自動テストが見逃す見た目のバグをお読みください。

要点

  • 1「element not found」はたいていバグではなくテストの問題です: 間違っているのはアプリケーションよりも、ロケーター、タイミング、コンテキストであることが多いのです。
  • 2ロケーターはありふれた理由で壊れます: 生成された ID、リデザイン、A/B テスト、翻訳、Shadow DOM、iframe、仮想化リストです。
  • 3どの戦略もリスクを移すだけです: CSS と XPath は構造に、ロールと名前は言葉に、テスト ID はチームの習慣に、自己修復は人の確認に依存します。
  • 4ロケーターに何も出さないアプリもあります: canvas、ゲーム、Citrix セッション、アクセシビリティツリーのないアプリは、見た目でしかテストできません。
  • 5GUI Test Studio には保守すべきセレクターもロケーターもありません: まずアプリケーションに尋ね、答えがなければ見た目で要素を見つけ、ユーザーに見えるものを確認します。

よくある質問

テスト自動化で「element not found」とはどういう意味ですか?

テストが ID、CSS セレクター、XPath などのロケーターで要素を要求し、時間内にページ上の何も一致しなかったという意味です。Selenium では NoSuchElementException、Playwright ではタイムアウトとして現れます。要素が本当にないこともありますが、多くの場合はロケーター、タイミング、コンテキストのどれかが間違っています。

ローカルでは要素が見つかるのに、CI では見つからないのはなぜですか?

たいていはコードではなく、実行環境が違うからです。遅いビルドエージェントではノートパソコンより遅れて要素が表示され、小さい画面ではメニューの裏に隠れ、別のテストデータでテキストが変わり、A/B テストでは別のバリアントが返されます。ロケーターを変える前に、失敗した実行のスクリーンショットか動画を確認してください。

XPath と CSS セレクターはどちらがよいですか?

どちらも単独では安全ではありません。Playwright のドキュメントが警告するとおり、どちらもページの組み立て方を表すため、構造が変わればどちらも壊れます。ロールと名前やテスト ID は長持ちしますが、それでも手で書いて最新に保つ必要があります。GUI Test Studio ではどちらも誰も書きません: テストが要素ごとの手がかりを自分で保持します。

Selenium や Playwright で動的 ID はどう扱えばよいですか?

それに頼ってテストを作らないでください: ビルドやページ読み込みのたびに変わる ID では、同じ要素を 2 回見つけられません。コードで書くテストでは、別のロケーターを手で書いて保守することになります。GUI Test Studio では書くものは何もありません: Web テストは、生成されたように見える ID を、人が読めるあらゆる手がかりの後ろ、要素への手がかりリストの末尾に回します。

自己修復型のテスト自動化は機能しますか?

属性が変わっても要素が残っている場合には役立ちます。本当に消えた要素は取り戻せず、誰かが書いて保守し続けるロケーターが出発点であることも変わりません。本当の変更が隠れないよう、修復は毎回確認してください。

アクセシビリティツリーのないアプリはどうテストしますか?

画面上で、見た目でテストします。ゲーム、canvas、グラフ、Citrix やリモートデスクトップのセッション、独自描画のプログラムの多くは、ロケーターが届くものを何も公開していません。GUI Test Studio はアプリケーションに手を加えずに、その要素を画像で見つけ、画面上で読んだテキストを確認します。

セレクターやロケーターなしでエンドツーエンドテストを自動化できますか?

できます。GUI Test Studio ではテストを記録するかプロンプトで説明するだけで、保守すべきセレクターもロケーターもありません。各アサーションは画面上の画像、テキスト、値の形、配置であり、GTS Engine + AI はまずアプリケーションに尋ね、答えがなければ見た目で、すべての要素を見つけます。

ボタンが意図的に変わったらどうなりますか?

アサーションは不合格になり、期待と実際の画像を並べて表示します。変更が意図どおりなら、信頼度レポートで「実際の画像を期待画像として採用」をクリックして保存すれば、コードを編集せずにテストが最新になります。

Selenium、Playwright、Cypress、AG Grid、Flutter、Qt、Java、Delphi、Citrix、Chrome、Edge、Firefox、Windows は、それぞれの所有者の商標です。

すべての記事