Pengenalan HtmlUnit

1. Pengenalan

Dalam artikel ini, kami akan memperkenalkan HtmlUnit, alat yang memungkinkan kami, dengan mudah, berinteraksi dan menguji laman HTML secara terprogram, menggunakan API JAVA .

2. Mengenai HtmlUnit

HtmlUnit adalah penyemak imbas tanpa GUI - penyemak imbas yang bertujuan untuk digunakan secara terprogram dan bukan secara langsung oleh pengguna.

Penyemak imbas menyokong JavaScript (melalui mesin Mozilla Rhino) dan boleh digunakan walaupun untuk laman web dengan fungsi AJAX yang kompleks. Semua ini dapat dilakukan dengan mensimulasikan penyemak imbas berasaskan GUI khas seperti Chrome atau Firefox.

Nama HtmlUnit dapat membuat Anda berfikir bahawa ini adalah kerangka pengujian, tetapi walaupun ia pasti dapat digunakan untuk pengujian, ia dapat melakukannya lebih dari itu.

Itu juga telah diintegrasikan ke dalam Spring 4 dan dapat digunakan dengan lancar bersama dengan rangka Spring MVC Test.

3. Muat turun dan Ketergantungan Maven

HtmlUnit boleh dimuat turun dari SourceForge atau dari laman web rasmi. Anda juga boleh memasukkannya ke dalam alat bangunan anda (seperti Maven atau Gradle, antara lain) seperti yang anda lihat di sini. Contohnya, ini adalah ketergantungan Maven yang dapat anda sertakan dalam projek anda:

 net.sourceforge.htmlunit htmlunit 2.23  

Versi terbaru boleh didapati di sini.

4. Ujian Web

Terdapat banyak cara di mana anda dapat menguji aplikasi web - yang kebanyakannya kami bahas di sini di laman web pada satu ketika atau yang lain.

Dengan HtmlUnit, anda dapat menguraikan HTML laman web secara langsung, berinteraksi dengannya sama seperti pengguna biasa dari penyemak imbas, memeriksa sintaks JavaScript dan CSS, mengirimkan borang dan menguraikan respons untuk melihat kandungan elemen HTMLnya. Semuanya, menggunakan kod Java tulen.

Mari mulakan dengan ujian mudah: buat WebClient dan dapatkan halaman pertama navigasi 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  

Anda dapat melihat beberapa amaran atau kesalahan semasa menjalankan ujian tersebut jika laman web kami mempunyai masalah JavaScript atau CSS. Anda harus membetulkannya.

Kadang kala, jika anda tahu apa yang anda lakukan (misalnya, jika anda melihat bahawa satu-satunya kesalahan yang anda lakukan adalah dari perpustakaan JavaScript pihak ketiga yang tidak boleh anda ubah), anda dapat mengelakkan kesalahan ini daripada membuat ujian anda gagal, memanggil setThrowExceptionOnScriptError dengan palsu :

@Test public void givenAClient_whenEnteringBaeldung_thenPageTitleIsCorrect() throws Exception  Java, Spring and Web Development tutorials", page.getTitleText()); 

5. Mengikis Web

Anda tidak perlu menggunakan HtmlUnit hanya untuk laman web anda sendiri. Lagipun, ia adalah penyemak imbas: anda boleh menggunakannya untuk menavigasi di mana-mana web yang anda suka, menghantar dan mengambil data mengikut keperluan.

Mengambil, mengurai, menyimpan dan menganalisis data dari laman web adalah proses yang dikenali sebagai pengikisan web dan HtmlUnit dapat membantu anda dengan mengambil dan mengurai bahagian.

Contoh sebelumnya menunjukkan bagaimana kita boleh memasuki laman web mana pun dan menavigasinya, mengambil semua maklumat yang kita mahukan.

Sebagai contoh, mari kita pergi ke arkib artikel Baeldung yang lengkap, arahkan ke artikel terbaru dan dapatkan tajuknya (pertama

teg). Untuk ujian kami, itu akan mencukupi; tetapi, jika kami ingin menyimpan lebih banyak maklumat, kami dapat, misalnya, mengambil tajuk (semua

tag) juga, dengan itu mempunyai idea asas mengenai artikel itu.

Sangat mudah untuk mendapatkan elemen dengan ID mereka, tetapi secara amnya, jika anda perlu mencari elemen, lebih mudah menggunakan sintaks XPath . HtmlUnit membolehkan kami menggunakannya, jadi kami akan melakukannya.

@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 h1 = (List) postPage.getByXPath("//h1"); Assert.assertTrue(h1.size() > 0); } 

Perhatikan dahulu bagaimana - dalam hal ini, kita tidak berminat dengan CSS atau JavaScript dan hanya ingin menguraikan susun atur HTML, jadi kita mematikan CSS dan JavaScript.

Dalam pengikisan web sebenar, anda boleh mengambil contoh tajuk h1 dan h2 , dan hasilnya akan seperti ini:

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

Anda boleh memastikan bahawa maklumat yang diambil sesuai dengan artikel terbaru di Baeldung:

6. Bagaimana dengan AJAX?

Fungsi AJAX boleh menjadi masalah kerana HtmlUnit biasanya akan mengambil halaman sebelum panggilan AJAX selesai. Sering kali anda memerlukannya untuk menguji laman web anda dengan betul atau mengambil data yang anda mahukan. Terdapat beberapa cara untuk mengatasinya:

  • Anda boleh menggunakan webClient.setAjaxController (NicelyResynchronizingAjaxController ()) baru . Ini menyegerakkan semula panggilan yang dilakukan dari utas utama dan panggilan ini dilakukan secara serentak untuk memastikan terdapat keadaan stabil untuk diuji.
  • Ketika memasuki halaman aplikasi web, anda dapat menunggu beberapa saat sehingga ada cukup waktu untuk membiarkan panggilan AJAX selesai. Untuk mencapainya, anda boleh menggunakan webClient.waitForBackgroundJavaScript (MILLIS) atau webClient.waitForBackgroundJavaScriptStartingBefore (MILLIS) . Anda harus memanggil mereka setelah mengambil halaman, tetapi sebelum menggunakannya.
  • Anda boleh menunggu sehingga beberapa syarat yang diharapkan berkaitan dengan pelaksanaan panggilan AJAX dipenuhi. Contohnya:
for (int i = 0; i < 20; i++) { if (condition_to_happen_after_js_execution) { break; } synchronized (page) { page.wait(500); } }
  • Daripada membuat WebClient () baru , yang secara lalai ke penyemak imbas web yang disokong terbaik, cubalah penyemak imbas lain kerana mungkin berfungsi dengan lebih baik dengan panggilan JavaScript atau AJAX anda. Contohnya, ini akan membuat webClient yang menggunakan penyemak imbas Chrome:
WebClient webClient = new WebClient(BrowserVersion.CHROME);

7. Contoh Dengan Musim Bunga

Sekiranya kita menguji aplikasi Spring kita sendiri, maka semuanya menjadi sedikit lebih mudah - kita tidak lagi memerlukan pelayan yang sedang berjalan .

Mari kita laksanakan aplikasi contoh yang sangat mudah: hanya pengawal dengan kaedah yang menerima teks, dan satu halaman HTML dengan borang. Pengguna dapat memasukkan teks ke dalam bentuk, menyerahkan borang, dan teks akan ditunjukkan di bawah borang itu.

Dalam kes ini, kami akan menggunakan templat Thymeleaf untuk halaman HTML itu (anda dapat melihat contoh Thymeleaf lengkap di sini):

@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 = "//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); } }

The key here is building the WebClient object using MockMvcWebClientBuilder from the WebApplicationContext. With the WebClient, we can get the first page of the navigation (notice how it's served by localhost), and start browsing from there.

As you can see, the test parses the form enters a message (in a field with ID “message”), submits the form and, on the new page, it asserts that the received text (field with ID “received”) is the same as the text we submitted.

8. Conclusion

HtmlUnit is a great tool that allows you to test your web applications easily, filling forms fields and submitting them just as if you were using the web on a browser.

Ia terintegrasi dengan lancar dengan Spring 4, dan bersama dengan Spring MVC Test framework mereka memberi anda persekitaran yang sangat kuat untuk membuat ujian integrasi semua halaman anda walaupun tanpa pelayan web.

Juga, dengan menggunakan HtmlUnit, anda dapat mengotomatisasi setiap tugas yang berkaitan dengan penyemakan imbas web, seperti mengambil, mengurai, menyimpan dan menganalisis data (pengikisan web).

Anda boleh mendapatkan kod di Github.