1. 概要

Selenium を使用して自動テストを行う場合、多くの場合、WebページまたはWebページの一部のスクリーンショットを撮る必要があります。 これは、特にテストの失敗をデバッグしたり、アプリケーションの動作がさまざまなブラウザー間で一貫していることを確認したりする場合に役立ちます。

このクイックチュートリアルでは、JUnitテストからSeleniumWebDriverを使用してスクリーンショットをキャプチャする方法をいくつか見ていきます。 Seleniumを使用したテストの詳細については、Seleniumの優れたガイドをご覧ください。

2. 依存関係と構成

pom.xmlにSeleniumの依存関係を追加することから始めましょう。

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
</dependency>

いつものように、このアーティファクトの最新バージョンは MavenCentralにあります。 さらに、Chromeドライバーの最新バージョンはウェブサイトからダウンロードできます。

次に、単体テストからChromeを使用するようにドライバーを構成しましょう。

private static ChromeDriver driver;

@BeforeClass
public static void setUp() {
    System.setProperty("webdriver.chrome.driver", resolveResourcePath("chromedriver.mac"));

    Capabilities capabilities = DesiredCapabilities.chrome();
    driver = new ChromeDriver(capabilities);
    driver.manage()
      .timeouts()
      .implicitlyWait(5, TimeUnit.SECONDS);

    driver.get("http://www.google.com/");
}

ご覧のとおり、これは ChromeDriver のかなり標準的なSelenium構成であり、ローカルマシンで実行されているChromeブラウザーを制御できます。 また、ページ上の要素を検索するときにドライバーが待機する時間を5秒に設定します。

最後に、テストを実行する前に、現在のブラウザウィンドウでお気に入りのWebページwww.google.comを開きます。

3. 表示可能領域のスクリーンショットを撮る

この最初の例では、Seleniumがすぐに提供するTakesScreenShotインターフェースを見ていきます。 名前が示すように、このインターフェイスを使用して、表示可能領域のスクリーンショットを撮ることができます。

このインターフェイスを使用してスクリーンショットを撮るための簡単な方法を作成しましょう。

public void takeScreenshot(String pathname) throws IOException {
    File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(src, new File(pathname));
}

この簡潔な方法では、最初にキャストを使用してドライバーをTakesScreenshotに変換します。 次に、指定されたOutputTypeを指定してgetScreenshotAsメソッドを呼び出し、画像ファイルを作成できます。

その後、 Apache Commons IO copyFile メソッドを使用して、ファイルを任意の場所にコピーできます。 かなりクール! わずか2行で、スクリーンショットをキャプチャできます

次に、単体テストからこのメソッドを使用する方法を見てみましょう。

@Test
public void whenGoogleIsLoaded_thenCaptureScreenshot() throws IOException {
    takeScreenshot(resolveTestResourcePath("google-home.png"));

    assertTrue(new File(resolveTestResourcePath("google-home.png")).exists());
}

この単体テストでは、ファイルが存在するかどうかを確認する前に、ファイル名 google-home.png を使用して、結果の画像ファイルを test /resourcesフォルダーに保存します。

4. ページ上の要素のキャプチャ

この次のセクションでは、ページ上の個々の要素のスクリーンショットをキャプチャする方法を見ていきます。 このために、Selenium3以降でネイティブにサポートされているスクリーンショットユーティリティライブラリであるaShotというライブラリを使用します

aShotはMavenCentral から入手できるため、pom.xmlに含めることができます。

<dependency>
    <groupId>ru.yandex.qatools.ashot</groupId>
    <artifactId>ashot</artifactId>
    <version>1.5.4</version>
</dependency>

aShotライブラリは、スクリーンショットをどの程度正確にキャプチャするかを構成するための FluentAPIを提供します。

次に、単体テストの1つからGoogleホームページからロゴをキャプチャする方法を見てみましょう。

@Test
public void whenGoogleIsLoaded_thenCaptureLogo() throws IOException {
    WebElement logo = driver.findElement(By.id("hplogo"));

    Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000))
      .coordsProvider(new WebDriverCoordsProvider())
      .takeScreenshot(driver, logo);

    ImageIO.write(screenshot.getImage(), "jpg", new File(resolveTestResourcePath("google-logo.png")));
    assertTrue(new File(resolveTestResourcePath("google-logo.png")).exists());
}

まず、 WebElement IDを使用してページ上で hplogo。 次に、新しいを作成します一発インスタンスを作成し、組み込みの射撃戦略の1つを設定します– ShootingStrategies.viewportPasting(1000)この戦略では、スクリーンショットを最大1秒間(1oooms)撮影している間、ビューポートをスクロールします。

これで、スクリーンショットをどのように構成するかについてのポリシーができました。

ページ上の特定の要素を内部的にキャプチャする場合、aShotは要素のサイズと位置を検出し、元の画像をトリミングします。 このために、 coordsProvider メソッドを呼び出し、WebDriverAPIを使用して座標を検索するWebDriverCoordsProviderクラスを渡します。

デフォルトでは、aShotは座標解決にjQueryを使用することに注意してください。 しかし、一部のドライバーはJavascriptに問題があります

これで、 takeScreenshot メソッドを呼び出して、driver要素とlogo要素を渡すことができます。これにより、Screenshotオブジェクトが含まれます。スクリーンキャプチャの結果。 前と同じように、画像ファイルを書き込んでその存在を確認することでテストを終了します。

5. 結論

このクイックチュートリアルでは、SeleniumWebDriverを使用してスクリーンショットをキャプチャする2つのアプローチを見てきました。

最初のアプローチでは、Seleniumを直接使用して画面全体をキャプチャする方法を確認しました。 次に、aShotと呼ばれる優れたユーティリティライブラリを使用して、ページ上の特定の要素をキャプチャする方法を学びました。

aShotを使用する主な利点の1つは、スクリーンショットを撮るときのWebDriverの動作が異なることです。 aShotを使用すると、この複雑さから私たちを抽象化し、使用しているドライバーに関係なく、透過的な結果が得られます。 サポートされているすべての機能を確認するには、ドキュメント全体を確認してください。

いつものように、記事の完全なソースコードは、GitHubから入手できます。