【第2回-中編】E2Eテストの歴史 -様々な実装技術-

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

第2回の前編では、E2Eテストの基幹部分とも言える要素探索の技術の変遷について扱いました。中編では、前編の内容も踏まえつつ、様々な実装技術について説明していきたいと思います。

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

実装技術の変遷

ここで言う実装技術とは、例えば第1回でテストコードを作成するのに使ったPlaywright Codegenのようなものを指します。単にテストコードを書くだけでなく、機械的にテストコードを生成する技術だったり、テストコードの可読性を上げるための書き方を考えたりなど、様々な試行錯誤が現在進行系で行われています。この記事では、筆者が知るいくつかの代表的な手法を取り上げたいと思います。

レコードアンドリプレイ

レコードアンドリプレイは、テスト対象のアプリケーションへの操作を「記録し、再生する」手法です。キャプチャアンドリプレイ、レコードアンドプレイバックなどとも呼びます。普段GUIを操作するのと全く同じ感覚で自動テストを実装できるので、非常にとっつきやすく、コーディングの知識がまるで無い人にとっても扱える他、ツールそのものへの学習も最小限に出来るのが特徴です。

原理としては、テスト対象のアプリケーションに記録用のコードを埋め込み、クリックや文字入力、スクロールなどのイベントを逐一記録していく、といったものです。

上記のように、誰でも簡単に使える反面、細かく記録しすぎてしまうことによるテストの不安定さや、生成されるテストコードの質が悪くメンテナンス性が著しく悪い、などの課題がありました。

特に、生成されるコードの質のところでは、当時使われていたページ表現の記法がCSSセレクターやXPathなどの内部構造であったこともあり、記録されたコードを後で読み返すと何をやっているのか良くわからない、ということもしばしばでした。

レコードアンドリプレイを採用するツールは多数ありますが、有名なのはSelenium IDEでしょう。その他Ghost Inspectorなども存在します。

レコードアンドリプレイはなぜダメだったのか

先述の通り、レコードアンドリプレイツールはたびたび批判の憂き目に合っています。書籍『システムテスト自動化標準ガイド』※1では、一章まるごと使ってこの手法への批判を記載しており、当時いかにこの手法によって苦しむ人が多かったのかが垣間見えます。

※1『システムテスト自動化 標準ガイド』(Mark Fewster、Dorothy Graham 著/テスト自動化研究会 訳/翔泳社)

レコードアンドリプレイの欠点として良く挙げられるのは以下のような点です。

  1. 記録されるロケーターの可読性が低かったり、ちょっとしたページの構造の変化に弱かったりする
  2. スクロールなど不要なステップの記録が多く、実行の不安定さにつながる
  3. テストコードが構造化されておらず、再利用性が低い

ですが、みなさんは第1回ですでにレコードアンドリプレイを経験して、(簡単な例ではあるものの)素早くテスト自動化ができることを実感していますね。また、(1) については第2回の前編でセマンティクスベースの要素探索により、可読性が高くページの構造の変化に強いロケーターを作れることを知っています。

(2) についても、第1回で使ったPlaywright Codegenではスクロールなどのステップは記録されておらず、余計なステップの記録はさほど発生しないことが分かったかと思います。

(3) については、それぞれのツールごとに考え方が異なりますが、後に記載するPage Object Model(POM)形式での構造化が一般的に使われており、サポートしているツールも多いです。

というわけで、過去にレコードアンドリプレイが使い物にならなかったのはコンセプトが悪かったからではなく、技術的に追いついていない部分が多かっただけというのが筆者の結論です。実際、Playwrightのようなツールにもビルトインされていますし、最近流行りのAIツールでもレコードアンドリプレイ形式を採用しているものは多いです(AIが操作した内容をレコードアンドリプレイで記録する、なんてツールもあります)。

キーワード駆動テスト

さて、レコードアンドリプレイでは操作を記録することでテストを作りましたが、キーワード駆動テストではキーワードと操作対象、データを組み合わせてテストを書きます。例えば、次のようなイメージです。

キーワード ロケーター データ
ページを開く http://example.com
文字を入力する textbox#email john.example.com
文字を入力する textbox#password password
クリックする span#button

少しでもプログラミングをかじったことがある方なら、なんとなくこの記法がプログラミングと自然言語の合いの子のように見えるかもしれません。
このように、ある特定の分野(ドメイン)の課題を解決するために使われる、人間にとって読みやすく機械にとっても処理しやすい言語をDSL(Domain Specific Language)と呼びます。つまり、キーワード駆動テストはE2Eテスト用のDSLです。

読みやすい一方、出来ることがDSLとして定義されたもののみに絞られてしまうことが難点です。また、場合によっては操作対象のロケーターを読みやすくするためにたくさんのエイリアスを設定しなければならず、テストのための実装が必要以上に増えてしまい、テストを書き始めるまでの労力が比較的大きいです。

キーワード駆動テストを採用するツールの代表例として、Robot Frameworkというものがあります。また、JavaScriptの文法の中でキーワード駆動のDSLのようなものを実現した珍しいツールでCodeceptJSというものもありますので一緒に紹介しておきます。

ページオブジェクトモデル

ページオブジェクトモデル(以下POM)は、一つのページに関連する要素と操作をひとまとめにしたものです。例えば、ログインページのページオブジェクトモデルは次のようになります。

// loginPage.js
class LoginPage {
  /**
   * @param {import('@playwright/test').Page} page
   */
  constructor(page) {
    this.page = page;
    this.emailInput = page.locator('#email');
    this.passwordInput = page.locator('#password');
    this.loginButton = page.locator('#login-form button.submit');
  }

  async goto() {
    await this.page.goto('https://example.com/login');
  }

  async fillEmail(email) {
    await this.emailInput.fill(email);
  }

  async fillPassword(password) {
    await this.passwordInput.fill(password);
  }

  async submit() {
    await this.loginButton.click();
  }

  async login(email, password) {
    await this.fillEmail(email);
    await this.fillPassword(password);
    await this.submit();
  }
}

module.exports = { LoginPage };

すると、テストコード側からはLoginPageという名前で、ページ内で使われる様々な要素と、ログインなどページ内で利用するアクションを定義できます。

// example.spec.js
const { test, expect } = require('@playwright/test');
const { LoginPage } = require('./loginPage');

test('ユーザーがログインできる', async ({ page }) => {
  const loginPage = new LoginPage(page);

  await loginPage.goto();
  await loginPage.login('john@example.com', 'securePassword!');

  // たとえばログイン成功後に表示されるテキストを確認
  await expect(page.locator('text=ようこそ')).toBeVisible();
});

利点としては、キーワード駆動テストと同様にページ内のロケーター記述を隠蔽できる点と、「ログイン」などの一連の操作をひとまとめにしたショートハンドを作成してテストコードの記述を省力化できる点にあります。また、特定のページに対する操作であることが一目で分かるため、コードの可読性向上にもつながります。加えて、ページの構成が変わった場合などにも、POMだけを直せば良いので、メンテナンス性が向上します。

反面、キーワード駆動テストと同様、POMそのもののメンテナンスが煩雑になりがちです。POMはページ内の要素とアクションを抽象化したものです。言い換えると、POMを定義することは、アプリケーションのUIそのものの実装と、そのページの見た目と操作方法を定義するテスト用の実装の2つを作る必要があります。これは典型的なダブルメンテで、面倒に思う場合も多いでしょう。

BDD(振る舞い駆動テスト)

BDD(振る舞い駆動テスト)は、その名の通りアプリケーションの「振る舞い」に着目した実装方法です。代表的なツールはCucumberです。

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

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