はじめに
最近、Selenium WebDrvierを利用する機会を得ている。
自動テストはやはり便利。打鍵やるのはバカらしいなって気分になる。
ただ、あんまり難しいことしようとするとどうしても作りこみが必要。
GebというWebDriverのラッパーがかゆいところに手が届く感じらしいので、
次回は検討しようかなぁ。
参考
脱・独自改造! GebでWebDriverをもっとシンプルに
使い始めて感じたことやTIPSをメモがてら残しておこうと思う。
1.ソースコードの自動生成
Selenium Builderというのが主流らしい。
Firefoxのアドイン。
その他にもSelenium IDEというのがある。
使った感じだとSelenium Builderの方が便利だ。
JavaとかRubyとかでエクスポートできる。 ただ、この自動生成したソースをそのまま使おうとするとなかなか渋い。それは現実的ではない。
2.DOMの取得
driver.findElement(By.id("id"))といった形
Byクラスで取り方を選べる。
By.id
By.name
By.linkText
By.tagName
By.cssSelector
By.xpath
など。
id > name > cssSelector > tagName > xpath当たりの順番で確度が高いらしい。
xpathというのはHTMLのルートからパス形式で追っていくもの。
DOMを確実に取得は出来るのだが、ページの項目が変わったりするとHTMLの組み直し
が発生するため変更にとても弱い。
そこらへんを考えると、PageObjectパターンを利用しつつ、
DIするのが懸命のよう。
3.画面キャプチャ
ブラウザ内の画面キャプチャ
TakesScreenshot screen = (TakesScreenshot) driver;
Path capture = Paths.get("C:\\hoge\\hogehoge");
Files.write(capture, screen.getScreenshotAs(OutputType.BYTES));
IEの場合、divが埋め込んであったりする画面は画面全体のキャプチャがうまく取れない。
IE、Firefox、Chromeなどブラウザやドライバの仕様によるところが大きいと思う。
参考
Selenium WebDriverで遊ぶ(Kazuhiraさん)
Selenium WebDriver でスクリーンショットを取得するときのtips(株式会社Pro-SPIRE 技術者ブログ)
端末全体(ブラウザ外も含む)のキャプチャは、awtのRobotを使う方法しかわからず渋い感じになった・・・。
try { Robot rbt; rbt = new Robot(); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension dim = tk.getScreenSize(); BufferedImage background = rbt.createScreenCapture(new Rectangle(0, -1, (int) dim.getWidth(), (int) dim.getHeight())); Path capture = outputPath.resolve(++fileNo + IMG_SUFFIX); ImageIO.write(background, "png", capture.toFile()); } catch (AWTException | IOException e) { throw new IllegalStateException(e); }
参考 http://alvinalexander.com/blog/post/jfc-swing/how-take-create-screenshot-java-swing-robot-class
4.クリック
new Actions(driver).click().build().perform();
またはnew Actions(driver).click(driver.findElement(By.id("id"))).build().perform();
5.ダブルクリック
new Actions(driver).doubleClick().build().perform();
またはnew Actions(driver).doubleClick(driver.findElement(By.id("id"))).build().perform();
6.右クリック
new Actions(driver).contextClick().build().perform();
またはnew Actions(driver).contextClick(driver.findElement(By.id("id"))).build().perform();
7.ショートカットキーとか
こんな感じ。
// Tab driver.findElement(By.id("id")).sendKeys(Keys.TAB); new Actions(driver).sendKeys(Keys.TAB); // Shift + Tab driver.findElement(By.id("id")).sendKeys(Keys.SHIFT, Keys.TAB); new Actions(driver)).sendKeys(Keys.SHIFT, Keys.TAB); // コピー driver.findElement(By.id("id")).sendKeys(Keys.CONTROL + "c"); new Actions(driver).sendKeys(Keys.CONTROL + "c"); // ペースト driver.findElement(By.id("id")).sendKeys(Keys.CONTROL+ "v"); new Actions(driver).sendKeys(Keys.CONTROL+ "v"); // 切り取り driver.findElement(By.id("id")).sendKeys(Keys.CONTROL+ "x"); new Actions(driver).sendKeys(Keys.CONTROL+ "x"); // 全選択 driver.findElement(By.id("id")).sendKeys(Keys.CONTROL+ "a"); new Actions(driver).sendKeys(Keys.CONTROL+ "a");
8.複数クリック
ちょっと苦労した。Ctrl押しながらクリックとか、Shift押しながらクリックとか。
ネットには
new Actions(driver).keyDown(Keys.SHIFT).click(driver.findElement(By.id("id"))).keyUp(Keys.SHIFT).build().perform();
とかよく書いてあるんだけど、これがうまく効いてくれなくて。。。
(単純なDOMじゃなくてリッチクライアントの操作をしようとしたせいかもしれない)
これもまたawtのRobotを使う渋い感じにした。
try { new Robot().keyPress(KeyEvent.VK_CONTROL); new Actions(driver).click(driver.findElement(By.id("A"))).build().perform(); new Actions(driver).click(driver.findElement(By.id("B"))).build().perform(); new Robot().keyRelease(KeyEvent.VK_CONTROL); } catch (AWTException e) { throw new IllegalStateException(e); }
参考
problem handling multiple windows in webdriver
Issue 3734: Clicking the link while holding down shift (using Actions), on Windows, does not open a new window
困ること
・エレメントが見つからないことがよくある。
実際にDOMを探しに行って無いケース(id間違い、ページ間違い)は
NoSuchElementExceptionというのが発生するのだけど、例外発生までのDOM検索がかなり長い。
多分、総当たりでページ全部を見に行ってしまっているためかと思う。
こうなるとテストが固まってしまう。というか実施者からすると待ちきれない感じになる。
言い換えると、テスト時間が伸びてテストコードを書くときのコストが上がる。
強制中断終了的なことをするとWebDriverのexeがプロセスに残ったままになってしまってめんどくさかったりとか。
(プロセスが残りまくるとPCが悲鳴を上げ始める)
多分driver.quit()というメソッドでexeに対して終了コマンドを送信しているんだと思うんだけど。
・エレメントが見つかっても触れないことが良くある
DOMは見つかったけどクリック出来ませんみたいなことが良くある。
ElementNotVisibleExceptionというのが発生するのだけど、
例外の粒度が荒くて、実際どういった原因でその例外が発生しているのかが追いにくい。
原因としてはこんな感じみたい。
・ページ上にの操作できる位置にない(スクロールしないとクリック出来ない位置にあるとか、ウィンドウサイズが小さすぎるとか)
・DOMはあるけどうまく描画されていない
・操作不能状態のDOMである(disabledとか、display:none;とか)
参考 テストツールとテスト自動化(2)(QUES TECH)
なかなか1つ1つつぶしていくのは難しかったりする。
そのポイントだけ解析しようとしても前後の副作用によって起きている事象だったりするので、
全部処理を流しなおしたりとか。
・検証が難しい
どうアサーションするのか。するとすれば何を期待値するか。
問題通知の仕組みはどうするか。
描画状態の検証とか細かいところはどうしても目で見ていくしかなかったり、
どこまで楽できるかっていうのを考えると悩む部分はある。
まとめ
一度慣れてしまえば、作り込みも苦労しないし、困るポイントも知っているので、 痛みは触り始めだけだと思う。
(まぁ変更が頻繁なシステムとかは過渡期にまた痛みを伴う気がするけど・・・・)
ブラウザ、システムの画面というのはどうしても変更が伴うので、
クラス設計としては変更への強さを求められるというところが作っていて楽しい。
毎日毎日全く同じ打鍵やってるようなところや、あまりに膨大な画面の再帰的にテストがあり、
打鍵ではなく自動化したいとかだと、採用を考えてみてもいいと思う。
0 件のコメント:
コメントを投稿