ページオブジェクトモデルについてまとめ

に公開

はじめに

ページオブジェクトモデルというデザインパターンについてまとめページです。
いくつかのサイトを参考に自分なりにまとめてみました。
Playwrightのテストコードをきれいに書くときなどに参考にしてください。

ページオブジェクトモデル(Page Object Model)とは

2Eテストにおけるデザインパターンの1つ

Webアプリケーションの各ページやコンポーネントをオブジェクトとしてモデル化し、テストコードの保守性を高める

主な特徴と利点

  • 再利用性の向
    • ページの要素やアクションをカプセル化して再利用しやすくする
  • 保守性の向上
    • UIの変更があった場合、修正がまとまっているのでメンテしやすい
  • コードの重複削減
    • 共通の操作や要素へのアクセスをクラスにまとめられるので意図しないコード重複を防ぎやすい

ベストプラクティス

  • テストロジックの分離

    • 各ページオブジェクトは特定のページやコンポーネントに関する操作のみ書いて、テストロジックは別途記述する。
  • 適切な粒度

    • 再利用性とメンテナンス性のバランスを考慮し、適切な粒度でページオブジェクトを設計します。
  • 明確なインターフェース

    • ページオブジェクトのメソッドは、その目的が明確に分かる命名にします。

ディレクトリ構造

tests/
├── pages/
│   ├── base/
│   │   └── BasePage.ts
│   ├── LoginPage.ts
│   └── XXXXXPage.ts
├── specs/
│   ├── login.spec.ts
│   ├── XXXXXX.spec.ts
│   └── XXXXXX.spec.ts
└── utils/
    └── helper.ts

ディレクトリの役割

  • pages

    • ページオブジェクトを置く
    • 命名ルール:[ページ名]Page.ts
  • page/base/:

    • 基底クラスをおく
    • 命名ルール:BasePage.ts
  • specs

    • テストケースファイルを置く

    • 命名ルール:[テストシナリオ].spec.ts

      ※テストシナリオじゃなくっても意味がわかれば良い気がする

  • usitl

    • 共通で使える共通ユーティリティを置く
    • 命名ルール:[機能]Utisl.ts

実装例

// ログインページのページオブジェクト例
class LoginPage {
  private usernameInput = element(by.id('username'));
  private passwordInput = element(by.id('password'));
  private loginButton = element(by.id('login-button'));

  async login(username: string, password: string) {
    await this.usernameInput.sendKeys(username);
    await this.passwordInput.sendKeys(password);
    await this.loginButton.click();
  }
}

// テストコード例
describe('ログインテスト', () => {
  const loginPage = new LoginPage();

  it('正常にログインできること', async () => {
    await loginPage.login('testuser', 'password123');
    // アサーション
  });
});

Discussion