1前書き

この記事では、HtmlUnitを紹介します。これは、JAVA APIを使用して、プログラムでHTMLサイトと対話してテストすることを簡単に可能にするツールです。


2 HtmlUnit

について


HtmlUnit

はGUIなしのブラウザです – ユーザが直接使用するのではなくプログラム的に使用することを目的としたブラウザです。

ブラウザはJavaScript(https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino[Mozilla Rhino]エンジンを介して)をサポートしており、複雑なAJAX機能を備えたWebサイトでも使用できます。これはすべて、ChromeやFirefoxなどの一般的なGUIベースのブラウザをシミュレートして実行できます。

HtmlUnitという名前は、それがテストフレームワークであると考えるようにあなたを導くかもしれませんが、それは確かにテストに使用することができますが、それはそれ以上のことをすることができます。

それはまたhttp://docs.spring.io/spring/docs/4.2.10.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#spring-mvc-test-server-htmlunit[Spring 4に統合]されているそしてSpring MVCテストフレームワークと一緒にシームレスに使用することができます。


3ダウンロードとMavenの依存関係

HtmlUnitはhttps://sourceforge.net/projects/htmlunit/[SourceForgeからダウンロード]またはhttp://htmlunit.sourceforge.net/[公式Webサイト]から入手できます。また、http://htmlunit.sourceforge.net/dependency-info.html[こちら]を見ることができるように、あなたはそれをあなたの構築ツール(とりわけMavenやGradleのような)に含めることができます。たとえば、これは現在プロジェクトに含めることができるMavenの依存関係です。

<dependency>
    <groupId>net.sourceforge.htmlunit</groupId>
    <artifactId>htmlunit</artifactId>
    <version>2.23</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Chtmlunit[ここ]にあります。


4 Webテスト

あなたがWebアプリケーションをテストすることができる多くの方法があります – 私たちがここでいくつかの点でここでカバーしたほとんど。

HtmlUnitを使用すると、サイトのHTMLを直接解析し、ブラウザから通常のユーザーと同じように対話したり、JavaScriptやCSSの構文を確認したり、フォームを送信したり、応答を解析してHTML要素の内容を確認できます。すべて、純粋なJavaコードを使用しています。

簡単なテストから始めましょう:

WebClient

を作成し、

www.baeldung.com

のナビゲーションの最初のページを取得します。

private WebClient webClient;

@Before
public void init() throws Exception {
    webClient = new WebClient();
}

@After
public void close() throws Exception {
    webClient.close();
}

@Test
public void givenAClient__whenEnteringBaeldung__thenPageTitleIsOk()
  throws Exception {
    HtmlPage page = webClient.getPage("/");

    Assert.assertEquals(
      "Baeldung | Java, Spring and Web Development tutorials",
        page.getTitleText());
}

このテストを実行すると、当社のWebサイトにJavaScriptまたはCSSの問題がある場合、いくつかの警告またはエラーが表示されることがあります。あなたはそれらを修正するべきです。

ときには、自分が何をしているのかを知っていれば(たとえば、修正してはいけないサードパーティのJavaScriptライブラリからのエラーだけがわかっているのであれば)



:

@Test
public void givenAClient__whenEnteringBaeldung__thenPageTitleIsCorrect()
  throws Exception {
    webClient.getOptions().setThrowExceptionOnScriptError(false);
    HtmlPage page = webClient.getPage("/");

    Assert.assertEquals(
      "Baeldung | Java, Spring and Web Development tutorials",
        page.getTitleText());
}


5 Webスクレイピング

自分のWebサイトだけにHtmlUnitを使用する必要はありません。それはブラウザです、結局のところ、あなたはあなたが好きなWebをナビゲートしたり、必要に応じてデータを送信したり取得したりするのに使用できます。

Webサイトからのデータの取得、解析、保存、および分析はWebスクレイピングとして知られるプロセスであり、HtmlUnitは取得および解析部分に役立ちます。

前の例は、どのWebサイトに入ってそれをナビゲートし、必要なすべての情報を取得するかを示しています。

たとえば、Baeldungの記事のフルアーカイブに行き、最新の記事に移動してそのタイトルを取得します(最初の

<h1>

タグ)。私たちのテストでは、それで十分でしょう。しかし、もっと多くの情報を保存したいのであれば、例えば見出し(すべての

<h2>

タグ)も検索することができます。そのため、この記事の内容についての基本的な考え方がわかります。

IDで要素を取得するのは簡単ですが、一般的に、要素を見つける必要がある場合はXPath構文を使用する方が便利です。 HtmlUnitはそれを使うことを許しているので、そうするでしょう。

@Test
public void givenBaeldungArchive__whenRetrievingArticle__thenHasH1()
  throws Exception {
    webClient.getOptions().setCssEnabled(false);
    webClient.getOptions().setJavaScriptEnabled(false);

    String url = "/full__archive";
    HtmlPage page = webClient.getPage(url);
    String xpath = "(//ul[@class='car-monthlisting']/li)[1]/a";
    HtmlAnchor latestPostLink
      = (HtmlAnchor) page.getByXPath(xpath).get(0);
    HtmlPage postPage = latestPostLink.click();

    List<HtmlHeading1> h1
      = (List<HtmlHeading1>) postPage.getByXPath("//h1");

    Assert.assertTrue(h1.size() > 0);
}

最初に注意してください – この場合、私たちはCSSやJavaScriptには興味がなく、HTMLレイアウトを解析したいだけなので、CSSとJavaScriptをオフにしました。

実際のWebスクレイピングでは、たとえば

h1



h2

のタイトルを使用できます。その結果は次のようになります。

Java Web Weekly, Issue 135
1. Spring and Java
2. Technical and Musings
3. Comics
4. Pick of the Week

取得した情報がBaeldungの最新の記事に対応していることを確認できます。

リンク:/uploads/latestBaeldung.png%201248w[]


6. AJAXについてはどうですか?

HtmlUnitは通常AJAX呼び出しが終了する前にページを取得するため、AJAX機能が問題になる可能性があります。多くの場合、Webサイトを正しくテストしたり、必要なデータを取得したりするためにそれらを完了する必要があります。対処方法はいくつかあります。

  • __webClient.setAjaxController(new

NicelyResynchronizingAjaxController())__。これにより、メインスレッドから実行された呼び出しが再同期され、これらの呼び出しは同期的に実行されて、テストする安定状態が確保されます。

  • Webアプリケーションのページに入るとき、あなたはいくつか待つことができます

秒なので、AJAX呼び出しを終了させるのに十分な時間があります。これを実現するには、

webClient.waitForBackgroundJavaScript(MILLIS)

または

webClient.waitForBackgroundJavaScriptStartingBefore(MILLIS)

を使用できます。あなたはページを検索した後、それを扱う前にそれらを呼び出すべきです。

  • の実行に関連する何らかの予想される状態まで待つことができます

AJAXの呼び出しは満たされています。例えば:

for (int i = 0; i < 20; i++) {
    if (condition__to__happen__after__js__execution) {
        break;
    }
    synchronized (page) {
        page.wait(500);
    }
}


  • new WebClient()

    を作成する代わりに、デフォルトでは

最もサポートされているWebブラウザは、あなたのJavaScriptやAJAX呼び出しでよりうまく機能するかもしれないので他のブラウザを試してください。たとえば、これはChromeブラウザを使用するwebClientを作成します。

WebClient webClient = new WebClient(BrowserVersion.CHROME);


7. Spring

を使った例

私たちが自分のSpringアプリケーションをテストしているなら、事はもう少し簡単になります – 私たちはもはや実行中のサーバーを必要としません** 。

テキストを受け取るメソッドを持つコントローラーと、フォームを持つ単一のHTMLページという、非常に単純なサンプルアプリケーションを実装しましょう。ユーザーはフォームにテキストを入力してフォームを送信することができ、テキストはそのフォームの下に表示されます。

この場合は、そのHTMLページ用にhttp://www.thymeleaf.org/[Thymeleaf]テンプレートを使用します(完全なThymeleafのサンプルリンクを見ることができます。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { TestConfig.class })
public class HtmlUnitAndSpringTest {

    @Autowired
    private WebApplicationContext wac;

    private WebClient webClient;

    @Before
    public void setup() {
        webClient = MockMvcWebClientBuilder
          .webAppContextSetup(wac).build();
    }

    @Test
    public void givenAMessage__whenSent__thenItShows() throws Exception {
        String text = "Hello world!";
        HtmlPage page;

        String url = "http://localhost/message/showForm";
        page = webClient.getPage(url);

        HtmlTextInput messageText = page.getHtmlElementById("message");
        messageText.setValueAttribute(text);

        HtmlForm form = page.getForms().get(0);
        HtmlSubmitInput submit = form.getOneHtmlElementByAttribute(
          "input", "type", "submit");
        HtmlPage newPage = submit.click();

        String receivedText = newPage.getHtmlElementById("received")
            .getTextContent();

        Assert.assertEquals(receivedText, text);
    }
}

ここで重要なのは、

WebApplicationContext

から

MockMvcWebClientBuilder

を使用して

WebClient

オブジェクトを構築することです。

WebClient

を使用すると、ナビゲーションの最初のページを取得し(

localhost

がどのように機能しているかに注意してください)、そこから閲覧を開始できます。

ご覧のとおり、テストはフォームを解析してメッセージを入力し(ID “message”のフィールドに)、フォームを送信し、新しいページでは受信したテキスト(ID “ID”のフィールド)が我々が提出したテキストと同じです。



HtmlUnitは、Webアプリケーションを簡単にテストできる優れたツールです。ブラウザでWebを使用している場合と同じように、フォームフィールドに入力して送信することができます。

これはSpring 4とシームレスに統合され、Spring MVC Testフレームワークと組み合わせることで、Webサーバーがなくてもすべてのページの統合テストを行うための非常に強力な環境を提供します。

また、HtmlUnitを使用すると、データの取得、解析、保存、分析(Webスクレイピング)など、Webブラウジングに関連するあらゆるタスクを自動化できます。


over on Github

のコードを入手できます。