Selenium Tips
随時追記中。。
Page Object Design Pattern
改行を送信
FooterWait
// footerが出るまで待機 public static void FooterArrivalWait() { Wait<WebDriver> wait = new WebDriverWait(driver, 30); wait.until(presenceOfElementLocated(By.id("Footer"))); }
・使用例
driver.get("http://www.yahoo.co.jp)";
Extract_Wait.FooterArraivalWait();
とか、
driver.findElement(By.id("Jigsaw"));
Extract_Wait.FooterArraivalWait();
このメソッドを挟むだけで、読み込み未遂による失敗・エラーは激減する。
毎日、約400ケースを回しているが、読み込み未遂による失敗・エラーは、ほぼ0。
テキストフィールド
public static void SendKeysANDClear(By by, String Key) { Extract_Wait.FooterArrivalWait(); try { Extract_Driver.driver.findElement(by).clear(); Extract_Driver.driver.findElement(by).sendKeys(Key); } catch (NoSuchElementException e) { fail("指定されたフィールドが見つからない:" + by); } }
ポップアップ
// 新しいウィンドウに切り替え public static void popupChangeNewWindow() { // ポップアップしたウィンドウのID取得 Default_Windows = driver.getWindowHandle(); String newWindowId = null; for (String id : driver.getWindowHandles()) { if (!id.equals(Default_Windows)) { newWindowId = id; } } try { Thread.sleep(2500); } catch (InterruptedException e) { } // ウィンドウ切り替え driver.switchTo().window(newWindowId); } // メイン画面へ戻す public static void popupChangeMainWindow() { driver.switchTo().window(Default_Windows); }
画像のURL取得
// 指定画像のURLを返す public static String returnImageURL(By by) { String ImageURL = null; try { ImageURL = driver.findElement(by).getAttribute("src"); } catch (NoSuchElementException e) { fail("画像が見つからない"); } return ImageURL; }
ダイアログ
// ダイアログでOKを選択する public static void dialogOK() { Alert confirm = driver.switchTo().alert(); confirm.accept(); } // ダイアログでキャンセルを選択する public static void dialogNO() { Alert confirm = driver.switchTo().alert(); confirm.dismiss(); }
Page Object Design Pattern(ページオブジェクトパターン)
ドキュメントに少し解説あり。
Page Object Design Pattern
・ページオブジェクトパターンで実装すると何が良いのか
・ページ操作とシナリオの分離
・メンテナンス性の向上
・テストケースの追加コストが低い(既にあるページオブジェクトを使える場合)
・なぜ、ページオブジェクトパターンか
ページオブジェクトパターンを知る前に100ケースほどテストを書いたのですが、サービスがアップデートされるたびに、シナリオとページ操作がぐっちゃぐちゃになっているテストコードから修正点を探し出すという、非常にバカなことをやっていました。
もちろん、漏れが起きるため、テストを回して修正、テストを回して修正、、、
一方、ページオブジェクトパターンで実装すれば、サービスがアップデートされれば、該当するページのテストを書き換えるだけで修正ができます。
もちろん、アップデートに伴い、シナリオを変更する必要も出てくるが、シナリオとページ操作が分離されているので、修正が容易でした。
ページオブジェクトパターンのメリットは、1度実装したページは使い回しが効くということです。
同じページ操作が複数のシナリオ内で出現することは、良くあること。。。
パターンで実装していなかった場合は、変なメソッドにまとめてしまったり、コピペで使いまわしたり。工数もかかるし、メンテナンス性は最悪というか皆無(笑・・えない)。
実際、シナリオ・ページ操作ぐっちゃぐちゃのテストケースを100個書いた後に、パターンに則って300ぐらい実装して身に染みた。
・書いたもの
・ページオブジェクトで使うインターフェース
・テストシナリオで必要となるページオブジェクト
・テストシナリオ
・テストデータを格納するYaml
・実際に使用しているインターフェース
public interface PageObject_Admin { //URL直叩き用 public void Open(); //未定 public void Close(); //各ページからログアウトするために public void Logout(); //トップページへのリンク public void Top(); //ヘルプ public void Help(); }
・ページ実装
public class PageObject001 implements PageObject_Master { static WebDriver driver; public PageObject001 () { driver = CreateDriverInstance.getDriver(); } // URL直叩き用 public void Open() { Extract_Driver.openBaseHTTP("/form/"); } // ログアウト用 public void Logout() { Extract_Auth.ToolLogout(); } public void Close() { } //トップへの遷移用 public void Top() { driver.findElement(By.linkText("トップ")).click(); Extract_Wait.FooterArrivalWait(); } public void Help() { } // タイトル public void inputComment_title(String Comment_title) { Extract_Input.SendKeysANDClear(By.id("title"),Comment_title); } // 本文 public void inputComment_body(String Comment_body) { Extract_Input.SendKeysANDClear(By.id("body"),Comment_body); } // 変更する public void doChange() { driver.findElement(By.id("change_submit")).click(); Extract_Wait.FooterArrivalWait(); driver.findElement(By.id("do_change")).click(); Extract_Wait.FooterArrivalWait(); driver.findElement(By.linkText("トップへ戻る")).click(); Extract_Wait.FooterArrivalWait(); } }
・テストシナリオ
public class TextCase0001 extends TestBase { @DataPoints public static Object[] getDataPoints() { // TODO getStackTraceは重いので、他の取得方法に変えたい。 String ClassInfo = Thread.currentThread().getStackTrace()[1] .getClassName(); return Extract_Yaml.ImportTestDataYaml_MAP(ClassInfo); } @Theory public void ゴニョゴニョする(Map<Object, Object> TestDataMAP) { PageObject001 PageObject001 = new PageObject001(); PageObject002 PageObject002 = new PageObject002(); PageObject003 PageObject003 = new PageObject003(); PageObject001 .Open(); P11_01.Login(TestDataMAP.get("ID").toString(), TestDataMAP.get("PW") .toString()); // ログイン状態の確認 Assertion_Condition.Auth_LogoutButtonAvailableCheck(); PageObject002.openP0003(); PageObject003.inputName(TestDataMAP.get("Name").toString()); PageObject003.inputName(TestDataMAP.get("TelNum").toString()); PageObject003.doSearch(); Assertion_TextElement .Assertion_ShowText_PerfectPatern(By.xpath("/html/body/div//table/tbody/tr/td/a"),TestDataMAP.get("Name").toString()); Assertion_TextElement .Assertion_ShowText_PerfectPatern(By.xpath("/html/body/div//table/tbody/tr/td/a"),TestDataMAP.get("TelNum").toString()); } }
・テストデータ用Yaml
1: ID: Jigsaw PW: Jigsawww Name: Jigsaw TelNum: 00-0000-0000
Firefoxのextensionでハマった
Firefoxのextensionを作る時、諸々のファイルが入ったフォルダを圧縮し、FXへ投げても、このアドオンは壊れているため云々が表示されてインストールできない。
だが、必要なファイル諸々を選択して圧縮後にリネームし、FXへ投げてみると、すんなりインストール出来てしまった。
フォルダ自体を選択するのではなく、必要なファイルを選択して圧縮する必要がある。
Seleniumで改行
driver.findElement(By.id("hogehoge")).sendKeys(Keys.ENTER);
Enter以外もいろいろ打てるらしい。
http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/Keys.html