WebDriverテストに失敗した後、自動的にスクリーンショットを取得

14807 ワード

UI自動化テストは実際にはそんなに安定していない.UI要素の変更のためかもしれないし、ネットワークの不安定のためかもしれない.テストに失敗したとき、WebDriverは通常いくつかの異常を投げ出す.異常情報で大体どこが間違っているのかはよくわかりますが、スクリーンショットを付けることができればなおさらです.特にRemote WebDriverでテストを実行すると、すべてのテストがSelenium Gridによって各ノードに配布されて実行され、異なるノードの構成が完全に同じではない可能性があります.
RemoteWebDriverを使用する場合は、実行テストで異常が発生した場合のスクリーンショットも異常の中に入れる機能を提供しています.具体的にはRemoteWebDriverの概要を参照してください.コードは簡単です.
public String extractScreenShot(WebDriverException e) {     Throwable cause = e.getCause();     if (cause instanceof ScreenshotException) {         return ((ScreenshotException) cause).getBase64EncodedScreenshot();     }     return null; }

どのようにして異常が発生したときに自動的に異常を捕まえることができますか?簡単に言えば、テストコードを書く人には透明で、テストコードを書くときに特に異常を処理する必要はありません.ここでは、WebDriverEventListenerインタフェースを実装し、RemoteWebDriverオブジェクトとWebDriverEventListenerインタフェースを実装するオブジェクトを一緒にパッケージして、EventFiringWebDriverオブジェクトをインスタンス化する必要があります.その後のことは普通のRemoteWebDriverオブジェクトを使うことと何の違いもありません.
WebDriverEventListenerインタフェースを実装する例:
public class MyEventListener implements WebDriverEventListener {     public void onException(Throwable ex, WebDriver arg1) {         String filename = generateRandomFilename(ex);         try {             byte[] btDataFile = Base64.decodeBase64(extractScreenShot(ex).getBytes());             File of = new File(filename);             FileOutputStream osf = new FileOutputStream(of);             osf.write(btDataFile);             osf.flush();             osf.close();         } catch (IOException e) {             e.printStackTrace();         }     }       private String generateRandomFilename(Throwable ex) {         Calendar c = Calendar.getInstance();         String filename = ex.getMessage();         int i = filename.indexOf('
'
); filename = filename.substring(0, i).replaceAll("\\s", "_") .replaceAll(":", "") + ".png"; filename = "" + c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH) + "-" + c.get(Calendar.HOUR_OF_DAY) + "-" + c.get(Calendar.MINUTE) + "-" + c.get(Calendar.SECOND) + "-" + filename; return filename; }   private String extractScreenShot(Throwable ex) { Throwable cause = ex.getCause(); if (cause instanceof ScreenshotException) { return ((ScreenshotException) cause).getBase64EncodedScreenshot(); } return null; }   @Override public void afterChangeValueOf(WebElement arg0, WebDriver arg1) { // TODO Auto-generated method stub   } }

EventFiringWebDriverオブジェクトをインスタンス化するには、次の手順に従います.
@Test public void setup(){     String remote_driver_url = "http://localhost:4444/wd/hub";     DesiredCapabilities capability = null;     capability = DesiredCapabilities.firefox();     WebDriverEventListener eventListener = new MyEventListener();     WebDriver driver = new EventFiringWebDriver(new RemoteWebDriver(new URL(                     remote_driver_url), capability)).register(eventListener); }

その後、テストに異常が発生した場合、basedir(これは自分で構成する)の下に、このようなpngスクリーンショット(2011-7-22-20-55-9-Element_is_not_currently_visible_and_so_may_not_be_interacted_with.png)が生成されます.
これらのコードセグメントでは,WebDriverEventListenerインタフェースおよびEventFiringWebDriverクラスを用いて,リスニングテストで投げ出された異常を実現し,異常に付属するスクリーンショットをpngファイルとして保存する方法を示した.
参考ブログ:Generating a screen capture on exception thrown with Selenium 2