🤖

React/Vueアプリを自動テストする際の留意ポイントまとめ

に公開

ウェブアプリケーションを自動テストする際に、テスト用のエレメントを動的に非表示で追加したいだったり、エレメントに値を入れる等の「ちょっとした」ことをJavaScriptのコードで実装したい場合があります。
通常のウェブアプリケーションであれば、DOMに対して直接操作すればうまくいく場合でも、React/Vueアプリの場合は思ったように動作しないといったことがあります。そこで、React/Vueアプリを自動テストする際の留意ポイントをいくつかまとめてみました。

1.🎯「見た目の値」と「内部状態」が一致するとは限らない

  • React/Vueでは、DOMの入力値(.value)がUIに反映されても、内部状態(state)が更新されていないことがある。
[ あなたのスクリプト ]
     |
     |  input.value = "123"
     ↓
[ DOM の input 要素 ] ←────── 反応なし
     |
     |  ※値は変わるが…
     ↓
[ React / Vue の内部 state ]
     × 変化を検知しない(=認識されない)
  • input.value = '1'だけでは不十分で、inputイベントの発火が必要。
    解決策: .valuenative setterを使って設定し、inputイベントをdispatchEventする。
[ あなたのスクリプト ]
     |
     |  nativeSetter.call(input, "123")
     |  input.dispatchEvent("input")
     ↓
[ DOM の input 要素 ]
     |
     |  "input" イベント発火!
     ↓
[ React / Vue の内部 state ]
     ○ 状態が更新される(=値が変わったと認識)
     ↓
[ バリデーション or 自動処理 ]
     → 自動で検証スタート or ボタン活性化など

🧪サンプルコード

const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
nativeSetter.call(input, value);
input.dispatchEvent(new Event('input', { bubbles: true }));

2.⌨️ ユーザー操作の模倣が最も確実

  • 多くのアプリはonKeyDown, onKeyUp, onInput, onFocusなどのキーボードイベントやフォーカスイベントに依存してバリデーションや状態更新を行なっている。
  • JavaScriptで自動入力する際は、「人間の入力に近い形」でイベントを再現するのが安全。

🧪サンプルコード

input.dispatchEvent(new KeyboardEvent('keydown', {...}));
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new KeyboardEvent('keyup', {...}));

3.⏱️ フレームワークの自動処理や遷移には「待ち」が必要

  • React/Vueは非同期レンダリングや遅延バインディングを行うため、DOMが表示された直後に入力しようとすると失敗することがある。
  • 「要素が存在するまで待つ」「一定時間待機」などを適切に挿入する。

🧪mablでは

  • wait untilを追加 - 特定の要素が表示されるまで待つ
  • waitを追加 - 次のステップに進む前に待つ
    wait on mabl

🧪サンプルコード

await delay(ms);

4.🎯 一括入力よりも逐次入力(auto-tab対応)

  • 分割入力形式(MFAコード入力など)では、1文字ごとにフォーカスが自動移動するケースが多い。
  • その場合、すべての入力フィールドをループで埋めるよりも、1文字ずつ入力 → アプリに任せてフォーカス移動 → 次の入力 が安全。

🧪サンプルコード

document.activeElement.focus();
nativeSetter.call(document.activeElement, digit);
document.activeElement.dispatchEvent(new Event('input', { bubbles: true }));
await delay(100); // auto-tabに対応

5.🧩 hidden要素の扱いには工夫が必要

  • style="display: none"position: absolute; left: -9999px にしてしまうと、mablのようなブラウザ上での操作をキャプチャーするツールでは要素を選べなくなってしまう。
  • opacity: 0 にして tabindex="-1" を追加することで、mablのようなツールから選択可能、かつアプリのauto-focusを邪魔しないhidden inputが作れる。

🧪サンプルコード

helper.style.opacity = '0';
helper.setAttribute('tabindex', '-1');

6.🧼 状態が外から見えない場合は内部イベントログで確認

  • フレームワークが値を内部で持っている場合、DOMに表示されていてもバリデーションやアクションが進まないことがある
  • ブラウザのデベロッパーツールを活用し、input.value, document.activeEleement, dispatchEvent の状態を確認する。

mablのローコードで「コードの柔軟性」と「ノーコードの生産性」をいいとこ取り

このエントリをご覧になっている方は、Web UI テストを実施する中で、

  • 「テストが思うように動かない」
  • 「一応動いているけど、今のやり方では生産性が上がらない」

……そんなモヤモヤを感じて辿り着かれたのではないでしょうか。

本文中でもご紹介したように、mabl を活用することで、コードとノーコードの“いいとこ取り”をしたテスト自動化が実現できます。

  • UIテストの基本的な部分は、ブラウザ操作をキャプチャー&リプレイで記録し、ノーコードで直感的に作成
  • 細かな制御が必要な場合には、JavaScriptコードでピンポイントにロジック追加や、REST API やデータベースとの連携も可能
  • さらに、文字列マッチングでは難しい画像・リスト・構造の検証には、生成AI(LLM)を活用したアサーションも利用可能
    • 例:ECサイトで「いちご」を検索 → 商品一覧の画像+説明が正しいか、カテゴリに沿った表示がされているか、など

このように、「簡単だけど強力」なテストが誰でも作れる時代になっています。
ぜひ一度、mabl のトライアルを通じてその価値をご体感ください。

Discussion