デザインパターンと開発戦略

(以前の場所: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests)

概要

時間の経過とともに、プロジェクトは多数のテストが積み上がる傾向があります。 テストの総数が増えると、コードベースに変更を加えることが難しくなります。 アプリケーションが正常に機能していても、1回の"単純な"変更で多数のテストが失敗する可能性があります。 これらの問題が避けられない場合もありますが、問題が発生した場合は、できるだけ早く稼働を再開する必要があります。 次のデザインパターンと戦略は、テストの作成と保守を容易にするためにWebDriverで以前に使用されています。 それらもあなたにとって役に立つかもしれません。

DomainDrivenDesign:アプリのエンドユーザーの言語でテストを表現します。
PageObjects:WebアプリのUIの単純な抽象化
LoadableComponent:PageObjectsをコンポーネントとしてモデリングします。
BotStyleTests:PageObjectsが推奨するオブジェクトベースのアプローチではなく、コマンドベースのアプローチを使用してテストを自動化します。

ロード可能なコンポーネント

それは何ですか?

LoadableComponentは、PageObjectsの作成の負担を軽減することを目的としたベースクラスです。 これは、ページがロードされることを保証する標準的な方法を提供し、ページのロードの失敗のデバッグを容易にするフックを提供することによってこれを行います。 これを使用して、テストの定型コードの量を減らすことができます。これにより、テストの保守が面倒になります。

現在、Selenium 2の一部として出荷されるJavaの実装がありますが、使用されるアプローチは、どの言語でも実装できるほど単純です。

簡単な使用方法

モデル化するUIの例として、新しいissueのページをご覧ください。 テスト作成者の観点から、これは新しい問題を提出できるサービスを提供します。 基本的なページオブジェクト(このシンプルな版を EditIssueBasic と呼び、後で EditIssue という LoadableComponent に発展させます)は次のようになります。

これをLoadableComponentに変換するには、これを基本型として設定するだけです。

この署名は少し変わっているように見えますが、それは、このクラスがEditIssueページをロードするLoadableComponentを表すことを意味します。

このベースクラスを拡張することにより、2つの新しいメソッドを実装する必要があります。

load メソッドはページに移動するために使用され、 isLoaded メソッドは正しいページにいるかどうかを判断するために使用されます。 このメソッドはブール値を返す必要があるように見えますが、代わりにJUnitのAssertクラスを使用して一連のアサーションを実行します。 アサーションは好きなだけ少なくても多くてもかまいません。 これらのアサーションを使用することで、クラスのユーザーにテストのデバッグに使用できる明確な情報を提供することができます。

少し手直しすると、PageObjectは次のようになります。

それは私たちをあまり信じられなかったようですよね? これまでに行ったことの1つは、ページに移動する方法に関する情報をページ自体にカプセル化することです。 つまり、この情報はコードベース全体に散らばっていません。 これは、テストで下記を実行できることも意味します。

EditIssue page = new EditIssue(driver).get();

この呼び出しにより、ドライバーは必要に応じてページに移動します。

ネストされたコンポーネント

LoadableComponentsは、他のLoadableComponentsと組み合わせて使用すると、より便利になります。 この例を使用すると、 “edit issue” ページをプロジェクトのWebサイト内のコンポーネントとして表示できます(結局のところ、そのサイトのタブからアクセスします)。 また、issue を報告するにはログインする必要があります。 これをネストされたコンポーネントのツリーとしてモデル化できます。

 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue

これはコードではどのように見えますか? まず、各論理コンポーネントには独自のクラスがあります。 それぞれの “load” メソッドは、親クラスを “get” します。 上記のEditIssueクラスに加えて、最終結果は次のようになります。

ProjectPage.java:

and SecuredPage.java:

EditIssueの “load” メソッドは次のようになります。

これは、コンポーネントがすべて相互に “ネストされている” ことを示しています。 EditIssueで get() を呼び出すと、そのすべての依存関係も読み込まれます。 使用例:

テストで Guiceberry などのライブラリを使用している場合は、PageObjectsの設定の前文を省略して、わかりやすく読みやすいテストを作成できます。

ボットパターン

(以前の場所: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests)

PageObjectsは、テストでの重複を減らすための便利な方法ですが、チームが快適にフォローできるパターンであるとは限りません。 別のアプローチは、より “コマンドのような” スタイルのテストに従うことです。

“ボット” は、生のSeleniumAPIに対するアクション指向の抽象化です。 つまり、コマンドがアプリに対して正しいことをしていないことがわかった場合、コマンドを簡単に変更できます。 例として:

これらの抽象化が構築され、テストでの重複が特定されると、ボットの上にPageObjectsを階層化することができます。

Example

**Action Bot**、**Loadable Component**、および **Page Object** を実装した `python + pytest + selenium` の例です。 A `pytest` fixture `chrome_driver`.

“Action Bot” implementation.

“Loadable Component definition.

“Loadable Component and Page Object” implementation.

Test cases implementation.

Test cases implementation with `pytest`.