SPA(Single Page Application)のE2Eテスト自動化で気をつけること3選


こんにちは。MagicPod カスタマーサクセスのIshiiです。

最近はフロントエンドのライブラリとして、React、Vue.js、Angularなどを使用しているWebアプリが増えてきています。このようなライブラリを用いてSPA(シングルページアプリケーション)を構築しているMagicPodユーザー様から、SPAの自動化に関するお悩みをお伺いする機会も多くあります。

本記事では、SPAのE2Eテスト自動化において特に注意すべき3つのポイントをご紹介し、それぞれの対策方法について詳しく解説します。安定したテスト自動化実現のお役に立てますと幸いです!


目次

SPA(シングルページアプリケーション)とは?

まずは簡単にSPAとは何かについてご説明します。
SPAとは、単一のHTMLページ上で動作し、ページ遷移を行わずに画面の内容を動的に更新するWebアプリケーションのことです。従来のマルチページアプリケーション(MPA)と比較しますと、SPAでは以下のような特徴があります。

ページ遷移がない

従来のMPAでは、ユーザーがリンクをクリックするたびにサーバーから新しいHTMLが返され、画面全体がリロードされます。一方SPAでは、初回読み込み時に必要なリソースを取得し、その後は部分的にデータを更新するだけなので、リロードが発生しません。

ユーザー体験(UX)の向上

ページ遷移による読み込み待ちがないため、操作がスムーズになり、ネイティブアプリのような快適さを実現できます。

APIとの連携が中心

表示の更新はサーバーからHTMLを受け取るのではなく、API(主にRESTやGraphQLなど)を通じてデータを取得・送信し、それをJavaScriptで描画します。MPAにおいてもAPIで取得するケースはありますが、SPAでは特に顕著です。

SPAを構築する際は、一般的にReact、Vue.js、Angularといったフロントエンドのライブラリが用いられます。
アプリのユーザー側としてはとても便利なのですが、この動的な性質により、E2Eテストにおいて従来のWebアプリケーションよりも課題が発生しやすくなります。
ここからはSPAのテスト自動化で発生する3つの失敗パターンを紹介し、対策方法について解説していきます。

①SPAのテストがタイミングの問題で失敗する

SPAでは、ユーザーの操作に応じて非同期でコンテンツが更新されるため、要素の表示タイミングが予測しにくくなります。
例えば、以下のような要因で、対象要素が表示されておらず失敗するケースがあります。

  • 初回のデータローディング
  • 動的に生成される要素の表示タイムラグ
  • APIからデータを取得して表示するまでのタイムラグ

上記のような場合、対象要素が表示されるまで待機することでテストを安定化することができます。

ここでのポイントは固定待ち時間は避け、明示的な待機をすることです。
具体的な対策について、MagicPodではどのように実装すれば良いかご紹介します。

「UI要素が表示されるまで待つ」コマンド

MagicPodには UI要素が表示されるまで待つコマンドがあります。
これを利用すると、指定した要素がDOMに現れるまで自動的に待機してくれるため、SPAでよくある「描画が終わる前にクリックして失敗」というケースを防ぐことができます。

例)ボタンが表示されるまで待ってからクリックするステップ


「画面全体の描画が終わるまで待つ」コマンド

画面全体の描画が終わるまで待つコマンドは、画面に一定時間変化がないことを基準として、描画の完了を検知します。
便利なコマンドなのですが、注意点として画面が継続的に変化するWebページでは、描画完了を正しく検知できない可能性があります。その場合は「UI要素が表示されるまで待つ」コマンドの使用がおすすめです!
参考ヘルプページ:待機コマンドについて

待機ポリシー

MagicPodでは、テスト全体に対して待機ポリシーを設定することができます。
待機ポリシーを安定性を重視にすることで、テストが要素を操作する際にすぐ見つからなくても最大10〜30秒程度リトライしながら待機するように出来ます。
詳しくは下記ヘルプページをご参照ください。
参考ヘルプページ:テスト実行時の待機時間の調整

②SPAのテストで要素が見つからず失敗する

SPAでは、DOMの構造が動的に変化します。そのため、操作したい要素が見つからず失敗してしまうことがあります。以下のような問題がよくある失敗の原因となります。

  • CSSクラス名、idの動的生成(例:button-a1b2c3など)
  • 要素の表示・非表示の頻繁な切り替え
  • 仮想DOMによる要素の再生成

要素が見つからない問題を回避するためにはロケーター(要素を特定するための目印)を工夫する必要があります。

ここからは具体的な事例を一つご紹介します。
以下のように選択肢が同じ問題が数問あり、各問題に回答すると次の問題にいくような作りとなっているイーラーニングのSPAがあるとします。

クイズGIF

ここで突然ですがクイズです!

Q.イーラーニングサイトの動作を確認するテストを作りたいです。
以下のようなステップを自動化する場合、アプリの作りによっては非常に不安定なテストになることがあります。どのような不安定さが生じうるでしょうか。


問1で選択肢「A」を選択する(XPathロケータ://input[@value='A'])


問1の回答をトリガーとし、問2の表示に切り替わる。
問2でも問1と同様の選択肢「A」を選択する(XPathロケータ://input[@value='A'])


それではどのような不安定さが生じるかを一緒に考えていきましょう。
問1と問2では選択肢Aをクリックするために同じXPathロケータ//input[@value='A']を使用しています。
もし問1で選択肢Aをクリック後、画面がなかなか問2に切り替わらず、問1が表示され続けてしまうとどうなるでしょうか。
指定したXPathロケータに該当する要素が存在すると判断されるため、問1の選択肢Aが再度クリックされてしまいます。結果として、問2でクリックがされないため、その後テストが失敗してしまいます。

今回ご紹介したケースは、前のセクションで解説した「待機」によって不安定さを解消する方法がまず考えられます。しかしながら各選択肢のロケーターが一緒であるため、表示されるまで待つことができません。(すでに「表示されている」と判断されてしまう)
代わりに、選択肢をクリックする前に「問2.正解を選んでください。」という問題文が表示されていることを確認すれば、安定化させることができそうです。しかし、もしたくさん問題がある場合、全ての問題に対して待機コマンドを入れる必要があるためテストケースが冗長になってしまいます。

本ケースでのお勧めは一意となるロケーターを設定することです。
例えば、以下のような各選択肢に何問目であるかが含まれるXPathロケータを設定することで、不安定さを解消することができます。
問1://input[@name='question1’ and @value=’A’]
問2://input[@name='question2' and @value=’A’]


MagicPodではこのように複数のロケーターが提案されるため、適切なロケーターを選ぶことが可能です。



もし一意になるロケーターが存在しない場合は、ソースコード上でdata-test-idなどのテスト用のidを追加していただくことをおすすめします。
他にもCSSクラス名、idの動的生成(例:button-a1b2c3など)の影響で不安定である場合にもテスト用のidの追加が効果的です。

テスト用のidの付与方法について詳しくはこちらのヘルプページをご参照ください。
参考ヘルプページ:ユニークIDの付与方法

③SPAのテストを作成した時と実行時で状態が異なり失敗する

SPAのテストでは、UIツリー(テスト対象画面を構成するHTMLやXMLの要素を、階層構造として表現したもの)の構造がテスト作成時と実行時で異なることによる失敗がよく起こります。具体的には以下のような原因で失敗することがあります。

一覧や検索結果が常に変化

SPAではクライアント側でAPIから取得したデータを元にDOMを再描画するため、テスト作成時に「N番目の要素」として存在していた項目が、実行時には順序が変わって存在しないことがあります。

リアクティブな更新

VueやReactなどのフレームワークでは、状態が更新されると即座にUIが書き換わるため、同じロケーターを指定しても期待した要素が存在しない場合があります。

「隠れ要素」の存在

SPAでは表示されていないページの要素がUIツリー上に存在することがあります。例えば、画面上には「送信」ボタンが一つだけ表示されているものの、裏側のUIツリー上では複数「送信」ボタンが存在し、失敗するといったことが起こります。

SPAのテストを安定させるためには

テストケース間の依存関係をなくす

テスト実行順に依存しないテストケース設計を行いましょう。
また、MagicPodにはアプリ起動時のオプションとして「プロセス再起動」を用意しています。複数テストケースを実行する際に、同じプロセスを使いまわすのではなく、プロセス再起動によりクリーンな環境でテストすることで不安定さを解消できます。
詳しくは以下のヘルプページをご参照ください。
参考ヘルプページ:単体実行では成功するテストが一括実行で失敗する

失敗した時はリトライする

E2Eテストはどうしても不安定さの解消が難しいケースがあります。そのようなケースに対応するため、MagicPodには「失敗時のリトライ」機能があります。詳しくは以下のヘルプページをご参照ください。
参考ヘルプページ:テストの安定性を向上させるには

テスト失敗時のトラブルシューティングは難しいと思いますので、ぜひお気軽にMagicPodサポートにお問い合わせください!

最後に

SPA(Single Page Application)のE2Eテストは不安定になりやすいですが、本記事でご紹介したように待機やロケーターの工夫によって安定させることができます。
MagicPodでは待機コマンドやロケーターの提案機能など、SPAのテスト自動化に有効活用できる機能を豊富にご用意しています。
また、SPAサイトのテストを自動化しているユーザーが多くいらっしゃるため、いただいたお問い合わせやご要望をもとに改善を行い日々進化しています。

「自社のSPAのテストは自動化できるだろうか?」というご相談も大歓迎です。
もしMagicPodが気になった方は、ぜひお気軽にお問い合わせください!
https://magicpod.com/consulting/


Mami Ishii

Mami Ishii

MagicPodカスタマーサクセスエンジニア。元々は法務系の仕事をしていたが、エクセルVBAを用いた事務作業の自動化にハマりWebエンジニアに転向。今の推し生成AIモデルはClaudeで、推しMagicPodコマンドはWeb APIコール。