【第2回-前編】E2Eテストの歴史 -要素探索技術の変遷-

こんにちは!みなさん、テストしてますか?

第1回では、まずはとにかくやってみようということで、VSCode拡張を使いながら簡単なE2Eテスト自動化にトライしてみました。初歩の初歩とはいえ、自動化がどんなものなのか、ざっくりイメージはついたのではないでしょうか。

記事一覧:モダンなE2Eテストの考え方をマスターしよう

第2回では、前・中・後編に分けて、E2Eテストを取り巻くパラダイム(考え方)や、使われるツールがどのように変わってきたのかについて書いていきます。この前編では、E2Eテストの重要な要素技術である「要素探索」の変遷について深堀っていきたいと思います。

なお、筆者自身は2017年ごろから自動テストに関わってきた身ですので、実は歴史を語るにはちょっと経験不足かもしれません。コメントがありましたらSNSなどでご連絡頂けますと助かります!

そもそもE2Eテストとは

E2Eテストとは「完全に統合済みのシステムを、ユーザーインターフェース(特にGUI)から操作する」テストのことを指します。

完全に統合済みというのは、システムを構成する様々なコンポーネントが全てビルドされた状態のことを指します。この特徴から、システムテストと呼ばれることもあります。

ユーザーインターフェースからというのは、ユーザーが実際にシステムを利用する際のインターフェースを用いるということを指します。この観点から、受け入れテストと呼ばれることもあります。

E2Eテストの目的

E2Eテストの主な目的は、実際に提供されるシステム上で(あるいは、非常に近い構成の上で)ユーザーがビジネスケースを達成できるかどうかを検証することです。

例えば、ECサイトであれば、以下のようなビジネスケースが考えられるでしょう。

  • ログイン〜購入まで
  • 商品を返品できる
  • 発送前の商品はキャンセルできる

これらのビジネスケースを、実際のシステムに近い構成でテストするのがE2Eテストです。これにより、単体テスト・結合テストのような小さい単位のテストでは見つけづらいコンポーネント間の齟齬や、各機能レベルでは問題なく動作するがビジネスケースは達成できない、といった問題を解決できます。

例えば、上記のECサイトの例なら、ログイン、カートに追加、購入といった機能レベルでは問題なく実装されているものの、住所の新規登録が出来ないので購入に進めない、といった問題を見つけることができます(さすがに、素朴すぎるケースではありますが、一例ということで)。

また、最近はWeb・モバイル問わず、クライアントとサーバーが相互に通信し合う構成のアプリが多いです。Webフロントエンドとバックエンドをそれぞれ個別に作って、実際の構成では様々なエラーが出ることもあるでしょう。こうした問題を見つけることもE2Eテストには期待されています。

要素探索技術の変遷

さて、E2Eテストとはどういうものか?についておさらいできたところで、ここからはE2Eテストの重要な技術である 要素探索 技術の変遷について見ていきましょう。

第1回のテストコードの中でも、要素探索は繰り返し出てきます。例えば、サンプルToDoアプリのテキストボックスをクリックするためのコードは、こんな感じで書かれていました。

TodoMVCのテキストボックス
TodoMVCのテキストボックス
await page.getByRole('textbox', { name: 'What needs to be done?' }).click();

このうち、 getByRole('textbox', { name: 'What needs to be done?' }) という部分が要素探索に当たります。

実は、この getByRole を用いた探索方法はここ数年で出てきた比較的新しい手法です。そのため、ちょっと古めの本などを読むと全然違うことが書いてあったりします。 getByRole はなぜ利用を推奨されているのか、他の方法とどう違うのかを理解するために、どんな変遷を辿ってきたのかについてこの記事でおさらいしておきましょう。

内部構造を用いた要素探索

例えば、テスト対象がWebアプリケーションのログインフォームだとします。

<form method="post" action="/login">
    <label for="email"> メールアドレス </label>
    <input id="email" />
    <label for="password"> パスワード </label>
    <input id="password" />
    <span id="button" class="login-btn">送信</span>
</form>

メールアドレス入力欄、パスワード入力欄、ログインボタンがあります。

これらのUI要素に、文字入力やクリックなどのアクションを行うためには、まずこれらの要素をHTML内(正確にはDOMツリー内)から探さなければいけません。ロケーターとは、この探索を行うために使う一意のキーのことを指します。
先ほどのHTMLに対してテストコードを書く場合、CSSセレクターXPath などのものを使ってそれぞれの要素を取得することができます。例えば、 CSSセレクター を使ってメールアドレスを取得するためのコードは以下のようなものになります。 #email という書き方で、 idemail のもの、という意味になります。

await page.locator("#email")

ところで、この id とは何のために使われるものでしょう?ウェブ開発者向けの技術ドキュメントサイトであるMDNによると、idは以下のような目的で使われるものと書いてあります。

ID 属性の目的は、リンク(フラグメント識別子を使用)、スクリプト、またはスタイル設定(CSS を使用)の際に、単一の要素を識別することです。

https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Global_attributes/id#%E8%A7%A3%E8%AA%AC

つまり、 id 属性はページ内で使われるJavaScriptやCSSのために使われるもので、これらの都合で変更される可能性があるわけです。

より具体的に言うと、上記のログインフォームは id の値を元にバックエンドサーバーにデータを送ります。そのため、バックエンドサーバーの仕様が変わった場合、フォームも変わる可能性があります。一例として、バックエンドサーバーが受け取る変数名が email から mailaddress に変わった場合、ログインフォームは以下のように変わります。

 <form method="post" action="/login">
-    <label for="email"> メールアドレス </label>
-    <input id="email" />
+    <label for="mailaddress"> メールアドレス </label>
+    <input id="mailaddress" />
    <label for="password"> パスワード </label>
    <input id="password" />
    <span id="button" class="login-btn">送信</span>
 </form>

もちろん、これに対応して、テストコードも変えなければいけません。

- const inputEmail = getElementById("email")
+ const inputEmail = getElementById("mailaddress")

ですが、E2Eテストの本来の目的と照らし合わせると、このように内部構造の変化の影響をテストコードが受けるのはおかしいはずです。E2Eテストの目的は ユーザーがビジネスケースを達成できるかどうか のはずなのに、目的が変わらないのにテストコードを直さないといけなくなってしまいます。これでは本末転倒です。

テスト用のIDを用いた要素探索

そこで、内部構造の代わりに、テスト用に一意のIDを振ろうという考え方が現れました。例えば、data-testid という属性を定義し、それをテスト用に使うことができます。

<form method="post" action="/login">
    <label for="email"> メールアドレス </label>
    <input id="email" data-testid="email" />
    <label for="password"> パスワード </label>
    <input id="password" data-testid="password" />
    <span id="button" class="login-btn" data-testid="submit">送信</span>
</form>

この場合、テストコードは次のように書けます。

await page.locator('[data=testid="email"]')

// 属性名が data-testid の場合は、
// Playwrightのショートハンドで次のようにも書ける
await page.getByTestId('email')

data- から始まる属性は データ属性 と呼ばれており、どんな属性も自由に定義でき、原則としてアプリケーションの振る舞いに影響を与えません。そのため、テスト用のIDを振るという用途にはぴったりです。

続きを読むにはログインが必要です。
ご利用は無料ですので、ぜひご登録ください。

SHARE

  • facebook
  • twitter

SQRIPTER

末村 拓也(すえむら たくや)

記事一覧

自動テストが好きなソフトウェアエンジニア。

【執筆・翻訳】
- テスト自動化実践ガイド(翔泳社・2024年)
- フルスタックテスティング(翔泳社・2025年)


- X: https://x.com/tsueeemura
- GitHub: https://github.com/tsuemura
- note: https://note.com/tsuemura

RANKINGアクセスランキング
#TAGS人気のタグ
  • 新規登録/ログイン
  • 株式会社AGEST
NEWS最新のニュース

Sqriptsはシステム開発における品質(Quality)を中心に、エンジニアが”理解しやすい”Scriptに変換して情報発信するメディアです

  • 新規登録/ログイン
  • 株式会社AGEST