37

初めてのポスター。私は長年 UI の自動化に取り組んできましたが、ページ オブジェクト モデルを紹介されたり、ページ オブジェクト モデルを使用するように指示されたりしたのはつい最近のことです。そのほとんどは常識であり、私がすでに使用している手法を含んでいますが、十分に合理的な説明を広範囲に検索したにもかかわらず、自分の心の中で正当化できなかった特定の細かい点があります. POM を自分のベスト プラクティスと統合しようとしているときに、この質問が驚きを引き起こしたので、ここの誰かが私を啓発してくれることを願っています。

http://code.google.com/p/selenium/wiki/PageObjectsから:

上記のコードは重要なポイントを示しています。ページの状態に関するアサーションは、PageObjects ではなく、テストが行​​う必要があります。もちろん、すべてのガイドラインと同様に、例外もあります。

http://seleniumhq.org/docs/06_test_design_considerations.html#chapter06-referenceから:

ページ オブジェクトの設計方法には多くの柔軟性がありますが、テスト コードの望ましい保守性を実現するための基本的なルールがいくつかあります。ページ オブジェクト自体は、検証やアサーションを行うべきではありません。これはテストの一部であり、ページ オブジェクトではなく、常にテストのコード内にある必要があります。ページ オブジェクトには、ページの表現と、メソッドを介してページが提供するサービスが含まれますが、テスト対象に関連するコードはページ オブジェクト内にあるべきではありません。

ページオブジェクト内に含めることができ、またそうすべきである単一の検証があり、それは、ページ、およびおそらくページ上の重要な要素が正しく読み込まれたことを検証することです。この検証は、ページ オブジェクトのインスタンス化中に行う必要があります。

これらの「ガイドライン」はどちらも潜在的な例外を認めていますが、基本的な前提には同意できませんでした。私は「ページメソッド」内でかなりの量の検証を行うことに慣れており、検証の存在は、さまざまなコンテキストで問題を見つけるための強力な手法だと思います (つまり、メソッドが呼び出されるたびに検証が行われます)。特定のテストの限られたコンテキストでのみ発生するよりも。

たとえば、AUT にログインしたときに、「ユーザーとしてログインしました」というテキストが表示されたとします。単一のテストでこれを明確に検証することは適切ですが、毎回検証したくないのはなぜですかログインが呼び出されますか?このアーティファクトは、ページが「正しくロードされた」かどうかに直接関連するものではなく、一般的に「テストされているもの」には関連していないため、上記の POM ガイドラインによれば、明らかにページ メソッドに含めるべきではありません。 ..しかし、可能な限り前もって考えずに、重要なアーティファクトを可能な限り頻繁に検証することにより、自動化の力を最大化するために、明らかにそこにある必要があるように思えます。検証コードをページメソッドに入れると、テストで心配することなく「無料で」多くの検証を取得できるため、自動化の力が倍増します。さまざまなコンテキストでのこのような頻繁な検証により、見つけられない問題が見つかることがよくあります。たとえば、検証がそのアーティファクトの単一のテストに限定されている場合。

言い換えれば、私はテスト固有の検証と「一般的な」検証を区別する傾向があり、後者が広範囲にページメソッドに含まれることは完全に適切/望ましいと思います。これにより、より薄いテストとより厚いページ オブジェクトが促進され、一般に、これらのガイドラインでは反対の競合が存在するにもかかわらず、より多くのコードを再利用することでテストの保守性が向上します。私は要点を逃していますか?ページメソッドで検証を望まない本当の理由は何ですか? 私が説明した状況は実際にこれらのガイドラインで説明されている「例外」の 1 つであり、したがって実際には POM と矛盾していませんか? ご意見ありがとうございます。-jn-

4

6 に答える 6

37

ガイドラインとして、アサーションはページ オブジェクトではなくテストで実行する必要があります。もちろん、これが実際的なアプローチではない場合もありますが、上記のガイドラインが正しいと言えるほどまれな場合もあります。ページ オブジェクトにアサーションを含めるのが嫌いな理由は次のとおりです。

  1. verifyアサーションがページ オブジェクトの別の場所に埋め込まれているメソッドを呼び出すだけのテストを読むのは非常にイライラします。可能であれば、テストが何を主張しているのかを明確にする必要があります。これは、アサーションがテストに直接含まれている場合に最適です。アサーションをテストの外のどこかに隠すと、テストの意図があまり明確になりません。

  2. ブラウザー テストでのアサーションはコストがかかる可能性があります。テストが非常に遅くなる可能性があります。数百または数千のテストがある場合、テストの実行時間に数分/時間が追加される可能性があります。これは悪いことです。アサーションを特定のアサーションに関係するテストだけに移動すると、テストがはるかに高速になり、関連する欠陥を引き続き検出できることがわかります。質問には次のものが含まれていました。

    ページメソッドに検証コードを入れると、自動化のパワーが倍増し、多くの検証を「無料」で取得できるようになります

    まあ、「自由は無料ではない」:)実際に増加しているのは、テストの実行時間です。

  3. いたるところにアサーションがあると、別の優れたガイドラインに違反します。「テストごとに 1 つのアサーション」( http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html )。私はそれに宗教的に固執しませんが、原則に従うようにしています. 可能であれば、テストは 1 つのことにのみ関心を持つべきです。

  4. 1 つのバグが原因で多くのテストが失敗し、テストすべきものをテストできなくなるため、テストの価値が低下します。

    たとえば、AUT にログインしたときに、「ユーザーとしてログインしました」というテキストが表示されたとします。単一のテストでこれを具体的に検証することは適切ですが、ログインが呼び出されるたびに検証したくないのはなぜですか?

    ページ オブジェクト クラスにアサーションがあり、予想されるテキストの変更がある場合、ログインするすべてのテストが失敗します。代わりにアサーションがテスト内にある場合、1 つのテスト (正しいメッセージを明確にテストするテスト) のみが失敗し、他のすべてのテストは実行を継続して他のバグを検出します。ログイン メッセージが間違っていることを伝えるのに 5,000 回のテストは必要ありません。1回のテストで十分です;)

  5. クラスに複数のことをさせることは、SOLIDの「S」に違反します。つまり、「単一責任の原則」( SRP) に違反します。クラスは 1 つのことだけを担当する必要があります。この場合、ページ オブジェクト クラスは、ページ (またはそのセクション) のモデル化のみを担当する必要があります。それ以上のことを行う場合 (例: アサーションを含む)、SRP に違反しています。

于 2012-07-20T10:50:09.843 に答える
12

私もこの推奨事項に時々苦労しました。このガイドラインの背後にある理由は、ページ オブジェクトを再利用可能にしておくことであり、ページ オブジェクト内に assert を配置すると、関連のない多数のテストで assert を再利用する能力が制限される可能性があると思います。そうは言っても、ヘッダーのキャプションをテストするなど、特定の検証方法をページ オブジェクトに配置しました。これは、変更されないページの要素のテスト ロジックをカプセル化するためのより良い方法です。

別のメモ - ドメイン モデルがページ オブジェクトとして再利用されている MVC アプリケーションを見てきました。これを正しく行うと、テスト ライブラリの冗長コードを大幅に減らすことができます。このパターンでは、ビュー モデルはテスト フレームワークへの参照を持たないため、明らかに、ビュー モデルにアサートを配置することはできません。

于 2012-06-20T20:34:53.650 に答える
6

ページ オブジェクトはアサーションを実行すべきではありません。これは、ページ オブジェクトがテスト フレームワークについて認識している必要があるためです (組み込み言語アサーションを使用している場合を除く)。ただし、要素を見つけてアクションを実行するには、ページの状態を知る必要があります。

重要なのは、「もちろん、すべてのガイドラインと同様に例外があります...」というステートメントにあります。

ページは、アサーションを実行するのではなく、例外をスローする必要があります。そうすれば、テストはアサーションをキャッチし、それに応じて保釈または行動することができます。例えば。

page = ProfilePage.open
try 
  page.ChangePassword(old, new)
catch notLoggedIn
  page.Login(user, pass)

assert page.contains "your password has been updated"

この限られた例では、何度も何度も確認する必要があるため、最善の方法ではないかもしれませんが、アイデアは得られます。状態を確認することもできます(2回)

if page.hasLoginDialog
  page.Login

if page.hasLoginDialog //(again!)
  assert.fail("can't login")

プロフィールページがあることを確認することもできます

try 
  page = site.OpenProfilePage
catch notOnProfilePage

または必要な要素があります profilepage.changePassword(old,new) catch elementNotFound を試してください

または例外をスローせずに

page = site.OpenProfilePage
if ! page instanceof ProfilePage

または複雑なチェック

assert page.looksLikeAProfilePage

重要なのはやり方ではありません。テストのロジックを最小限に抑えたいが、ページ オブジェクトをテスト フレームワークに結び付けたくない場合 - 結局のところ、同じオブジェクトをスクレイピングやデータ生成に使用したり、別のテストで使用したりする可能性があります。独自のアサーションを持つフレームワーク。

必要に応じて、アサーションをテスト ケースからテスト ヘルパー メソッドにプッシュできます。

page = site.GoToProfilePage
validate.looksLikeProfilePage(page)

言語が mixin をサポートしている場合、これは mixin の絶好の機会です。そのため、きれいなページ オブジェクトを保持し、健全性チェックを mixin できます。

于 2012-10-11T21:26:01.427 に答える
4

同じアサーションが複数のテスト メソッドで使用される可能性があることを知ったとき、これは私を困惑させます。たとえば、アサーション固有のメソッドを書く -

public PaymentPage verifyOrderAmount(BigDecimal orderAmount) {      
   Assertion.assertEquals(lblOrderAmount.getText(), orderAmount, "Order Amount is wrong on Payment details page"); 
   return this; 
}

これで、必要なすべてのテストで再利用できます。複数のシナリオを扱う複数のテストで同じアサーション ステートメントを繰り返す代わりに。言うまでもなく、テストに応じてメソッドで複数のアサーションを連鎖させることができます。

 .verifyOrderAmount(itemPrice)
 .verifyBankAmount(discountedItemPrice)
 .verifyCouponCode(flatDiscountCode.getCouponCode()) 

ページ オブジェクトがページによって提供されるサービスを表すと想定される場合、アサーション ポイントもページによって提供されるサービスではないでしょうか。

于 2013-02-11T05:24:30.493 に答える
3

@Mattがページオブジェクトでドメインモデルを再利用することで時間を節約できるかもしれませんが、テストの匂いではありません。テストロジックはドメインモデルを十分に明確にしています(何を達成しようとしているかによって異なります)。

元の質問に戻ります。本当にPageObjectでアサーションを実行する必要がある場合は、isLoaded()メソッドを使用できるselenium loadablecomponent <>を使用するか、loadablecomponent<>クラスにカスタムアサーションを含めることができます。これにより、ページオブジェクトにアサーションがなくなりますが、ロード可能なコンポーネントでアサーションを実行できます。以下のリンクを参照してください...

https://github.com/SeleniumHQ/selenium/wiki/LoadableComponent

_夢想家

于 2012-12-12T10:26:19.380 に答える
-1

私は著者にこれ以上同意できませんでした。

テスト メソッドにアサーションを追加すると、「早期に失敗」するのに役立ちます。アサーションとは、ボタンをクリックした後に特定のページが読み込まれたかどうかなどを確認することを意味します (いわゆる一般的なアサーション)。

実行時間がそれほど長くなるとは本当に思いません。UI の自動化はデフォルトでは遅いため、数ミリ秒のチェックを追加してもそれほど大きな違いはありませんが、トラブルシューティングが容易になり、初期の障害が報告され、コードが再利用しやすくなります。

ただし、UI テストの種類によっても異なります。たとえば、エンド ツー エンド テストを大部分が正のパスで実装している場合、テスト メソッド内で、ボタンをクリックすると実際にページが開くことを確認することは理にかなっています。ただし、ネガティブなシナリオをたくさん書いている場合は、必ずしもそうとは限りません。

于 2019-09-30T14:42:51.130 に答える