Pattern)を利用して変更に強いテストを作成する方法]Java、Eclipse、JUnitに関連した技術情報のブログです。WebDriverでは利用できません。IDEの機能改善により対応されるかも知れませんが、期待薄だと感じています。Pattern(ページオブジェクトパターン)」を利用するしかないです。言うことで、本エントリーでは以下の内容を説明させていただきます。Patternが必要な理由UIマップファイルを利用しないテストスクリプトの問題点Selenium入門ももう5回目となりますが、今までのテストスクリプトは全てdriver.findElementの引数にロケータを記述してきました。Javadriver.findElement(By.id("nameInputId")).clear();1driver.findElement(By.id("nameInputId")).clear();やJavadriver.findElement(By.xpath("//*[@id='testForm']/input[2]")).click();1driver.findElement(By.xpath("//*[@id='testForm']/input[2]")).click();のような物です。簡単な文字列だとしても、By.id(“nameInputId”)が多く出現するスクリプトは変更に強いとは言い難いです。変更に強い!、これはソフトウェア開発者の永遠の課題ですよね。IDEでテストスクリプトを生成する時は、その問題点に気付きにくいのですが、何も考えないでテストを作り上げてしまうと大変なことになります。時間の経過とともテストのメンテのコストが大きくなっていき、最後には放置される。そんな状況を何度も経験してきました。IDEでテストスクリプトを生成した後にリファクタリングを行うとの手順でも問題はないのですが、標準機能でリファクタリングを回避できますので便利です。Pattern(ページオブジェクトデザインパターン)」を利用する必要があります。WebDriver(Java/Junit4)の基本コマンド]と同じ物となります。定型の記載とaddPageでページの追加、エイリアスの追加を記載したjs(JavaScript)ファイルを作成します。ファイルのエンコーディングはUTF-8にする必要があります。エイリアスはページ毎に一意である必要があります。違うページには同じエイリアスが追加できることを意味します。うーん、イマイチな説明ですね・・・ページAにエイリアス=youserNameページBにエイリアス=youserNameが存在しても問題ないと言うことです。2つのエイリアスのロケータは異なっていても問題ないです。'name=username');34行目で”testpage”という名前でページを追加し37、39行目でエイリアスを追加しています。37行目はname属性の値がusernameのエレメントに”username”と言うエイリアスを与えています。ロケータの指定方法はロケータのスタティクス=識別文字列となります。By.cssであれば、css=実際のCSSセレクタの値By.nameであれば、name=name属性の値By.tagNameであれば、tagname=タグ名になります。IDEのメニューの[オプション]-[設定]をクリックします。参照ボタンをクリックし、先ほどのファイルを選択します。選択後にOKボタンをクリックします。IDEを再起動します。再起動後にUIマップファイルが利用できるようになります。IDEから選択し直す直すことでUIマップファイルが利用可能になります。考えてもイマイチな実現方法ですよね・・・ページ毎にエイリアスを一意にするとの考え方は正しい選択だと思います。それによってUIマップファイルのエイリアスを自動選択できないとの動作もある程度は納得できます。IDEの録画スクリプトに埋め込む方法があると思います。WebDriverで使えないのであれば「UIマップファイル」を利用する意味が感じられません。説明に利用するアプリseleniumのテスト用サイトを利用させていただきます。http://example.selenium.jp/reserveApp/複数画面で、入力と確認画面があるサンプルを用意しようとも思ったのですが、上記のサイトのアプリでやりたいことが充足できていますので、これを例に説明させていただきます。正しい値が入力された状態で「次へ」確認画面に遷移します。正しくない値が入力された状態で「次へ」エラー画面に遷移します。Pattern(ページオブジェクトパターン)とはテスト対象ページ毎のクラスとテストケースクラスを分離し、変更に強いテストを作成するための仕組みとなります。「入力画面」のページクラス(PageObject)、「入力画面」のテストクラス「確認画面」のページクラス、「確認画面」のテストクラス「エラー画面」のページクラス、「エラー画面」のテストクラスの6クラスを作成します。厳密に言うと「確認画面」と「エラー画面」は同じURLですので同じクラスとしてもOKですが、今回は明示的に異なるページクラスにマッピングしてみます。ページクラスは画面操作の部分を担当し、テストケースクラスは画面への入力値の保持し、ページクラスのメソッド呼び出しを行うことによりWebブラウザを操作と検証の実行を行います。これによって、入力項目が異なるだけのテストの変更コストが格段に削減できます。それ以外にも工夫次第で様々な効果が期待できます。ページクラスのインスタンス化とWebElementの特定を行うために以下の2つの仕組みが提供されいます。PageFactory(ページファクトリー)ページクラスの作成時にはPageFactoryのinitElementsメソッドを利用します。この操作を行うことによってSeleniumが提供しているページオブジェクトパターンが利用できるようになります。HogePage.class);FindByアノテーションorg.openqa.selenium.WebElement型のクラスメンバに@FindByアノテーションを付与することにより、クラスメンバにアクセスした時にSeleniumがアノテーションで指定されたHTML要素をインジェクションしてくれます。hogeElement;}上記の例ではhogeElementにアクセスすると、HTMLのname属性がhogeの要素が返却されます。実際にテストを実装してみる入力画面から確認画面の遷移のテストまでを実装してみる第一段階として、入力画面への入力と確認画面への遷移の部分を実装してみます。検証する内容は宿泊日(開始)と宿泊日(終了)のみとしています。dateFormat.format(calendar.getTime());}}ポイントは84行目のinputSuccessDataメソッドです。reserveTerm(宿泊期間)を引数として取ります。・その他の値はデフォルトなので変更なしとなっています。このようにシステム日付を利用することによってテストデータを固定で指定する必要がなくなります。当然ですが、固定の日付をテストする必要がある場合はテストケースに固定値でセットする必要があります。情報を入力した後に確認画面で表示される宿泊日(開始)と宿泊日(終了)もクラスメンバにセットしています。このデータを利用して確認画面に表示される宿泊日(開始)と宿泊日(終了)の検証を行うためです。dateToElement.getText();}}ConfirmPageは特に説明は不要かと思います。is(inputPage.getExpectedDateTo()));}}ポイントは34行目からのテストメソッドとなります。36行目で入力画面に入力を行い、「OK」ボタンをクリックし、戻り値にConfirmPageクラスのインスタンスが返却されます。Pattern」ではこのように画面操作後の遷移先のページをページオブジェクトのメソッドが返却するように実装します。すればテストケースで今どのページを操作しているかを意識しなくても済むからです。(と言っても遷移先のオブジェクトの型は意識しているので微妙ではあります。)38行目でConfirmPageのインスタンスの宿泊開始日と、期待される宿泊開始日の比較40行目でConfirmPageのインスタンスの宿泊終了日と、期待される宿泊終了日の比較をそれぞれ行っています。エラー確認画面のテストを追加してみる入力画面から確認画面への遷移のテスト例は説明できましたので、次はエラー画面への遷移を追加してみます。入力画面のデフォルトの内容のまま「次へ」ボタンをクリックすると、エラー画面に遷移して「お名前が指定されていません」とのエラーメッセージが表示されます。(本来であれば入力画面でエラーメッセージが表示されるべきですが・・・、まあ画面遷移のテストには持ってこいですね!、きっとその意図で作成されているのでしょう!!)・InputPageクラスInputPageクラスにinputFailDataメソッドを追加して、上記の操作を実装してみました。ErrorPage.class);}今度は遷移先がエラー画面ですので、ErrorPageのインスタンスを返却しています。・ErrorPageクラスErrorPageは以下のようになります。errorMessageDiv.getText();}}エラーメッセージはid=”errorcheck_result”に対応するdivに囲まれているテキストとなりますので、対応するHTML要素にアクセスするメンバー変数と、そのメンバー変数からテキストを取り出すメソッドgetErrorMessageを含んでいます。・InputTestクラスInputTestクラスにはテストケースであるinputPage_errorを追加しました。is("お名前が指定されていません"));}処理内容はコメントのままですので、説明は不要と思います。今回の例だけでは、ページオブジェクトデザインパターンの有効性がイマイチ訴求できないとは思いますが、変更に強いテストを作成するためには必須の仕組みとなりますので、是非ご利用ください。Pattern)を利用して変更に強いテストを作成する方法]」は以上です。スポンサードリンク関連記事Eclipse4.4(Java)におけるビルド・パス関係の設定方法[ビルド・パス上に必要なプロジェクト/プロジェクト参照の追加]Eclipse4.4(Java)におけるビルド関係のビルド・パス上の「ビルド・パス上に必要なプロジェ記事を読むSelenium利用時のトラブルシューティング方法[クリック編]Seleniumは便利なテスト自動化ツールですし、今後は更なる利用者の増加が見込まれます。eclipseとJUnitで確認する。Java8(JDK8)では、ラムダ式の導入を前提とした、コレクションAPIの新機能が追加されました。(4.7.1)を利用してJUnit5の公式ガイドの内容を実践してみる。JUnit5が本格的に利用できる環境が整ってきました。Eclipse[5:クラスに関する基礎知識(メソッドをJUnitを使って説明)]クラスに関する基礎知識シリーズも、いよいよメソッドを残すのみとなりました。WebDriverでは利用できません。コメントをキャンセルメールアドレスが公開されることはありません。(4.7.1)を利用してJUnit5の公式ガイドの内容を実践してみる。JUnit5が本格的に利用できる環境が整ってきました。Pattern)を利用して変更に強いテストを作成する方法]Java、Eclipse、JUnitに関連した技術情報のブログです。