מבוא ל- HtmlUnit

1. הקדמה

במאמר זה נציג את HtmlUnit, כלי המאפשר לנו בפשטות, לקיים אינטראקציה עם אתר HTML ולבדוק אותו באופן פרוגרמטי, באמצעות ממשקי API של JAVA.

2. אודות HtmlUnit

HtmlUnit הוא דפדפן ללא ממשק משתמש - דפדפן המיועד לשימוש באופן תכנותי ולא באופן ישיר על ידי משתמש.

הדפדפן תומך ב- JavaScript (באמצעות מנוע Mozilla Rhino) ויכול לשמש גם עבור אתרים עם פונקציות AJAX מורכבות. כל זה יכול להיעשות לדמות דפדפן טיפוסי המבוסס על GUI כמו Chrome או Firefox.

השם HtmlUnit יכול לגרום לך לחשוב שזו מסגרת בדיקה, אך למרות שניתן בהחלט להשתמש בה לבדיקה, היא יכולה לעשות הרבה יותר מזה.

הוא שולב גם באביב 4 וניתן להשתמש בו בצורה חלקה יחד עם מסגרת מבחן MVC של אביב.

3. הורדה ותלות Maven

ניתן להוריד את HtmlUnit מ- SourceForge או מהאתר הרשמי. כמו כן, אתה יכול לכלול אותו בכלי הבניין שלך (כמו Maven או Gradle, בין היתר) כפי שאתה יכול לראות כאן. למשל, זו התלות של Maven שאתה יכול לכלול כרגע בפרויקט שלך:

 net.sourceforge.htmlunit htmlunit 2.23 

את הגרסה החדשה ביותר תוכלו למצוא כאן.

4. בדיקת רשת

ישנן דרכים רבות בהן ניתן לבדוק יישום אינטרנט - שאת רובן סקרנו כאן באתר בשלב זה או אחר.

בעזרת HtmlUnit תוכלו לנתח ישירות את ה- HTML של האתר, לתקשר איתו בדיוק כמו שמשתמש רגיל היה מהדפדפן, לבדוק תחביר JavaScript ו- CSS, להגיש טפסים ולנתח את התגובות כדי לראות את התוכן של רכיבי ה- HTML שלו. כל זה, באמצעות קוד ג'אווה טהור.

נתחיל במבחן פשוט: צור a WebClient וקבל את העמוד הראשון בניווט של www.baeldung.com:

פרטי WebClient webClient; @ לפני init () הריק הציבורי זורק חריג {webClient = WebClient חדש (); } @ לאחר סגירה בטלנית ציבורית () זורק חריג {webClient.close (); } @Test ציבורי בטל שניתן AClient_whenEnteringBaeldung_thenPageTitleIsOk () זורק חריג HtmlPage page = webClient.getPage ("/"); Assert.assertEquals ("באלדונג 

אתה יכול לראות כמה אזהרות או שגיאות בעת הפעלת בדיקה זו אם באתרנו יש בעיות JavaScript או CSS. כדאי לתקן אותם.

לפעמים, אם אתה יודע מה אתה עושה (למשל, אם אתה רואה שהשגיאות היחידות שיש לך הן מספריות JavaScript של צד שלישי שלא כדאי לך לשנות), אתה יכול למנוע משגיאות אלה לגרום למבחן שלך להיכשל, להתקשר setThrowExceptionOnScriptError עם שֶׁקֶר:

@ מבחן הריק פומבי בהתחשב ב- AClient_whenEnteringBaeldung_thenPageTitleIsCorrect () זורק מדריכי חריגות Java, Spring ו- Web Development ", page.getTitleText ()); 

5. גירוד ברשת

אינך צריך להשתמש ב- HtmlUnit רק עבור אתרי האינטרנט שלך. אחרי הכל, מדובר בדפדפן: אתה יכול להשתמש בו כדי לנווט בכל רשת שתרצה, לשלוח ולאחזר נתונים לפי הצורך.

אחזור, ניתוח, אחסון וניתוח נתונים מאתרים הוא התהליך המכונה גירוד באינטרנט ו- HtmlUnit יכול לעזור לך בחלקים באחזור ובניתוח.

הדוגמה הקודמת מראה כיצד אנו יכולים להיכנס לכל אתר ולנווט בו, תוך אחזור כל המידע שאנחנו רוצים.

למשל, בואו נעבור לארכיון המאמרים המלא של באלדונג, נעבור למאמר האחרון ונשיג את כותרתו (ראשית

תָג). למבחן שלנו זה יספיק; אך אם נרצה לאחסן מידע נוסף, נוכל למשל לאחזר את הכותרות (הכל

תגים) גם כן, וכך יש מושג בסיסי על מה המאמר.

קל להשיג אלמנטים לפי תעודת הזהות שלהם, אך באופן כללי, אם אתה צריך למצוא אלמנט זה נוח יותר השתמש בתחביר XPath. HtmlUnit מאפשר לנו להשתמש בו, כך נעשה זאת.

@Test הציבור בטל givenBaeldungArchive_whenRetrievingArticle_thenHasH1 () זורק חריג {webClient.getOptions (). SetCssEnabled (false); webClient.getOptions (). setJavaScriptEnabled (false); Url מחרוזת = "/ full_archive"; דף HtmlPage = webClient.getPage (url); מחרוזת xpath = "(// ul [@ class = 'auto-monthlisting'] / li) [1] / a"; HtmlAnchor latestPostLink = (HtmlAnchor) page.getByXPath (xpath) .get (0); HtmlPage postPage = latestPostLink.click (); רשימה h1 = (רשימה) postPage.getByXPath ("// h1"); Assert.assertTrue (h1.size ()> 0); } 

שים לב ראשית כיצד - במקרה זה, אנו לא מעוניינים ב- CSS ולא ב- JavaScript ורק רוצים לנתח את פריסת ה- HTML, ולכן ביטלנו את CSS ו- JavaScript.

בגרידה ברשת אמיתית, אתה יכול לקחת למשל את ה- h1 ו h2 כותרות, והתוצאה תהיה משהו כזה:

Java Web Weekly, גיליון 135 1. Spring ו- Java 2. Technical ו- Musings 3. קומיקס 4. בחירת השבוע

אתה יכול לבדוק שהמידע שאוחזר תואם את המאמר האחרון ב- Baeldung:

6. מה לגבי AJAX?

פונקציות AJAX יכולות להיות בעיה מכיוון ש- HtmlUnit בדרך כלל ישחזר את הדף לפני סיום שיחות AJAX. פעמים רבות אתה צריך שהם יסיימו כדי לבדוק כראוי את האתר שלך או לאחזר את הנתונים שאתה רוצה. ישנן כמה דרכים להתמודד איתן:

  • אתה יכול להשתמש webClient.setAjaxController (חדש NicelyResynchronizingAjaxController ()). זה מסנכרן מחדש שיחות שבוצעו מהשרשור הראשי ושיחות אלה מבוצעות באופן סינכרוני כדי להבטיח שיש מצב יציב לבדיקה.
  • כשנכנסים לדף של אפליקציית אינטרנט, אתה יכול לחכות כמה שניות כדי שיהיה מספיק זמן לתת לשיחות AJAX להסתיים. כדי להשיג זאת, אתה יכול להשתמש webClient.waitForBackgroundJavaScript (MILLIS) אוֹ webClient.waitForBackgroundJavaScriptStartingBefore (MILLIS). עליך להתקשר אליהם לאחר אחזור הדף, אך לפני שתעבוד איתו.
  • אתה יכול לחכות עד שיתקיים תנאי צפוי כלשהו הקשור לביצוע שיחת AJAX. לדוגמה:
עבור (int i = 0; i <20; i ++) {if (condition_to_happen_after_js_execution) {break; } מסונכרן (עמוד) {page.wait (500); }}
  • במקום ליצור a WebClient חדש (), המוגדר כברירת מחדל בדפדפן האינטרנט הנתמך ביותר, נסה דפדפנים אחרים מכיוון שהם עשויים לעבוד טוב יותר בשיחות JavaScript או AJAX שלך. למשל, זה ייצור webClient המשתמש בדפדפן Chrome:
WebClient webClient = חדש WebClient (BrowserVersion.CHROME);

7. דוגמה עם אביב

אם אנו בודקים את יישום האביב שלנו, הדברים נעשים מעט קלים יותר - אנחנו כבר לא צריכים שרת פועל.

בואו ניישם אפליקציית דוגמה פשוטה מאוד: רק בקר עם שיטה שמקבלת טקסט, ודף HTML יחיד עם טופס. המשתמש יכול להזין טקסט לטופס, להגיש את הטופס, והטקסט יוצג מתחת לטופס זה.

במקרה זה נשתמש בתבנית Thymeleaf עבור דף HTML זה (תוכל לראות דוגמה מלאה של Thymeleaf כאן):

@RunWith (SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration (classes = {TestConfig.class}) בכיתה ציבורית HtmlUnitAndSpringTest {@Wac פרטי WebApplicationContext פרטי; פרטי WebClient webClient; @ לפני התקנת הריק הציבורי () {webClient = MockMvcWebClientBuilder .webAppContextSetup (wac) .build (); } @ מבחן פומבי בטל givenAMessage_whenSent_thenItShows () זורק חריג {String text = "שלום עולם!"; דף HtmlPage; מחרוזת url = "// localhost / message / showForm"; עמוד = webClient.getPage (url); HtmlTextInput messageText = page.getHtmlElementById ("הודעה"); messageText.setValueAttribute (טקסט); טופס HtmlForm = page.getForms (). קבל (0); HtmlSubmitInput submit = form.getOneHtmlElementByAttribute ("קלט", "סוג", "שלח"); HtmlPage newPage = submit.click (); מחרוזת receivedText = newPage.getHtmlElementById ("קיבל") .getTextContent (); Assert.assertEquals (receivedText, text); }}

המפתח כאן הוא בניית ה- WebClient באמצעות אובייקט MockMvcWebClientBuilder מ ה WebApplicationContext. עם ה WebClient, אנו יכולים לקבל את הדף הראשון בניווט (שימו לב כיצד הוא מוגש על ידי מארח מקומי), והתחל לגלוש משם.

כפי שאתה יכול לראות, המבחן מנתח את הטופס מזין הודעה (בשדה עם "הודעת" מזהה), מגיש את הטופס ובדף החדש הוא קובע שהטקסט שהתקבל (שדה עם מזהה "התקבל") הוא זהה לטקסט שהגשנו.

8. מסקנה

HtmlUnit הוא כלי נהדר שמאפשר לך לבדוק את יישומי האינטרנט שלך בקלות, למלא שדות טפסים ולהגיש אותם ממש כאילו אתה משתמש באינטרנט בדפדפן.

זה משתלב בצורה חלקה עם אביב 4, ויחד עם Spring MVC Test Test הם נותנים לך סביבה חזקה מאוד לבצע בדיקות אינטגרציה של כל הדפים שלך גם ללא שרת אינטרנט.

כמו כן, באמצעות HtmlUnit תוכלו לבצע אוטומציה של כל משימה הקשורה לגלישה באינטרנט, כגון אחזור, ניתוח, אחסון וניתוח נתונים (גירוד באינטרנט).

אתה יכול לקבל את הקוד ב- Github.