Introduktion til HtmlUnit

1. Introduktion

I denne artikel introducerer vi HtmlUnit, et værktøj, der giver os mulighed for, enkelt sagt, interagere med og teste et HTML-sted programmatisk ved hjælp af JAVA API'er.

2. Om HtmlUnit

HtmlUnit er en browser uden GUI - en browser beregnet til at blive brugt programmatisk og ikke direkte af en bruger.

Browseren understøtter JavaScript (via Mozilla Rhino-motoren) og kan bruges selv til websteder med komplekse AJAX-funktioner. Alt dette kan gøres ved at simulere en typisk GUI-baseret browser som Chrome eller Firefox.

Navnet HtmlUnit kan få dig til at tro, at det er en testramme, men selvom det helt sikkert kan bruges til test, kan det gøre så meget mere end det.

Det er også integreret i Spring 4 og kan bruges problemfrit sammen med Spring MVC Test framework.

3. Download og Maven-afhængighed

HtmlUnit kan downloades fra SourceForge eller fra det officielle websted. Du kan også medtage det i dit bygningsværktøj (som Maven eller Gradle, blandt andre) som du kan se her. For eksempel er dette den Maven-afhængighed, du i øjeblikket kan medtage i dit projekt:

 net.sourceforge.htmlunit htmlunit 2.23 

Den nyeste version kan findes her.

4. Webtest

Der er mange måder, hvorpå du kan teste en webapplikation - hvoraf de fleste vi dækkede her på siden på et eller andet tidspunkt.

Med HtmlUnit kan du direkte analysere et websteds HTML, interagere med det som en normal bruger fra browseren, kontrollere JavaScript og CSS-syntaks, indsende formularer og analysere svarene for at se indholdet af dens HTML-elementer. Alt sammen ved hjælp af ren Java-kode.

Lad os starte med en simpel test: Opret en Webklient og få den første side i navigationen af www.baeldung.com:

privat WebClient webClient; @Før offentlig ugyldig init () kaster undtagelse {webClient = ny WebClient (); } @ Efter offentlig tomrumslukning () kaster undtagelse {webClient.close (); } @Test offentligt ugyldigt givetAClient_whenEnteringBaeldung_thenPageTitleIsOk () kaster undtagelse HtmlPage side = webClient.getPage ("/"); Assert.assertEquals ("Baeldung 

Du kan se nogle advarsler eller fejl, når du kører denne test, hvis vores websted har JavaScript- eller CSS-problemer. Du skal rette dem.

Nogle gange, hvis du ved hvad du laver (for eksempel hvis du ser, at de eneste fejl, du har, er fra tredjeparts JavaScript-biblioteker, som du ikke skal ændre), kan du forhindre, at disse fejl får din test til at mislykkes, når du ringer setThrowExceptionOnScriptError med falsk:

@Test offentligt ugyldigt givetAClient_whenEnteringBaeldung_thenPageTitleIsCorrect () kaster Exception Java, Spring og Web Development tutorials ", page.getTitleText ()); 

5. Webskrabning

Du behøver ikke bruge HtmlUnit kun til dine egne websteder. Det er trods alt en browser: du kan bruge den til at navigere på ethvert web, du kan lide, sende og hente data efter behov.

Hentning, parsing, lagring og analyse af data fra websteder er den proces, der kaldes webskrabning, og HtmlUnit kan hjælpe dig med hentning og parsing af dele.

Det forrige eksempel viser, hvordan vi kan komme ind på et hvilket som helst websted og navigere gennem det og hente alle de oplysninger, vi ønsker.

Lad os for eksempel gå til Baeldungs ​​fulde artikelarkiv, navigere til den nyeste artikel og hente dens titel (først

tag). Til vores test vil det være nok; men hvis vi ønskede at gemme mere info, kunne vi for eksempel hente overskrifterne (alle

tags), og har således en grundlæggende idé om, hvad artiklen handler om.

Det er let at få elementer efter deres ID, men generelt, hvis du har brug for at finde et element, er det mere praktisk at brug XPath-syntaks. HtmlUnit giver os mulighed for at bruge det, så vi gør det.

@Test offentligt ugyldigt givetBaeldungArchive_whenRetrievingArticle_thenHasH1 () kaster undtagelse {webClient.getOptions (). SetCssEnabled (false); webClient.getOptions (). setJavaScriptEnabled (false); Streng url = "/ fuld_arkiv"; HtmlPage-side = webClient.getPage (url); Streng xpath = "(// ul [@ class = 'car-monthlisting'] / li) [1] / a"; HtmlAnchor latestPostLink = (HtmlAnchor) page.getByXPath (xpath) .get (0); HtmlPage postPage = latestPostLink.click (); Liste h1 = (Liste) postPage.getByXPath ("// h1"); Assert.assertTrue (h1.size ()> 0); } 

Først bemærk hvordan - i dette tilfælde er vi ikke interesseret i CSS eller JavaScript og vil bare analysere HTML-layoutet, så vi slukkede CSS og JavaScript.

I en rigtig webskrabning kan du f.eks. Tage h1 og h2 titler, og resultatet ville være sådan noget:

Java Web Weekly, nr. 135 1. Forår og Java 2. Technical and Musings 3. Tegneserier 4. Ugens valg

Du kan kontrollere, at de hentede oplysninger faktisk svarer til den seneste artikel i Baeldung:

6. Hvad med AJAX?

AJAX-funktioner kan være et problem, fordi HtmlUnit normalt henter siden, før AJAX-opkaldene er afsluttet. Mange gange har du brug for dem til at afslutte for at teste dit websted korrekt eller for at hente de data, du ønsker. Der er nogle måder at håndtere dem på:

  • Du kan bruge webClient.setAjaxController (ny NicelyResynchronizingAjaxController ()). Dette resynkroniserer opkald, der udføres fra hovedtråden, og disse opkald udføres synkront for at sikre, at der er en stabil tilstand at teste.
  • Når du går ind på en side i en webapplikation, kan du vente i nogle sekunder, så der er tid nok til at lade AJAX-opkald slutte. For at opnå dette kan du bruge webClient.waitForBackgroundJavaScript (MILLIS) eller webClient.waitForBackgroundJavaScriptStartingBefore (MILLIS). Du skal ringe til dem efter hentning af siden, men inden du arbejder med den.
  • Du kan vente, indtil en forventet betingelse relateret til udførelsen af ​​AJAX-opkaldet er opfyldt. For eksempel:
for (int i = 0; i <20; i ++) {if (condition_to_happen_after_js_execution) {pause; } synkroniseret (side) {page.wait (500); }}
  • I stedet for at oprette en ny WebClient (), der som standard er den bedst understøttede webbrowser, skal du prøve andre browsere, da de muligvis fungerer bedre med dine JavaScript- eller AJAX-opkald. For eksempel opretter dette en webClient, der bruger en Chrome-browser:
WebClient webClient = ny WebClient (BrowserVersion.CHROME);

7. Et eksempel med foråret

Hvis vi tester vores egen Spring-ansøgning, bliver tingene lidt lettere - vi har ikke længere brug for en kørende server.

Lad os implementere en meget enkel eksempelapp: bare en controller med en metode, der modtager en tekst, og en enkelt HTML-side med en formular. Brugeren kan indtaste en tekst i formularen, indsende formularen, og teksten vises under denne formular.

I dette tilfælde bruger vi en Thymeleaf-skabelon til den HTML-side (du kan se et komplet Thymeleaf-eksempel her):

@RunWith (SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration (klasser = {TestConfig.class}) offentlig klasse HtmlUnitAndSpringTest {@Autowired privat WebApplicationContext wac; privat WebClient webClient; @Før offentlig ugyldig opsætning () {webClient = MockMvcWebClientBuilder .webAppContextSetup (wac) .build (); } @Test offentlig ugyldighed givenAMessage_whenSent_thenItShows () kaster undtagelse {String text = "Hej verden!"; HtmlPage-side; String url = "// localhost / message / showForm"; side = webClient.getPage (url); HtmlTextInput messageText = page.getHtmlElementById ("meddelelse"); messageText.setValueAttribute (tekst); HtmlForm form = page.getForms (). Get (0); HtmlSubmitInput send = form.getOneHtmlElementByAttribute ("input", "type", "send"); HtmlPage newPage = send.click (); Streng receivedText = newPage.getHtmlElementById ("modtaget") .getTextContent (); Assert.assertEquals (receivedText, text); }}

Nøglen her er at opbygge Webklient objekt ved hjælp af MockMvcWebClientBuilder fra WebApplicationContext. Med Webklient, vi kan få den første side i navigationen (bemærk, hvordan den serveres af lokal vært), og start browsing derfra.

Som du kan se, analyserer testen formularen en meddelelse (i et felt med ID "meddelelse"), indsender formularen, og på den nye side hævder den, at den modtagne tekst (felt med ID "modtaget") er det samme som den tekst, vi indsendte.

8. Konklusion

HtmlUnit er et fantastisk værktøj, der giver dig mulighed for let at teste dine webapplikationer, udfylde formularfelter og indsende dem, som om du brugte internettet i en browser.

Det integreres problemfrit med Spring 4, og sammen med Spring MVC Test framework giver de dig et meget kraftfuldt miljø til at lave integrationstest af alle dine sider, selv uden en webserver.

Ved hjælp af HtmlUnit kan du også automatisere enhver opgave, der er relateret til webbrowsing, såsom hentning, parsing, lagring og analyse af data (webskrabning).

Du kan få koden over på Github.


$config[zx-auto] not found$config[zx-overlay] not found