event_listeners

Event Listeners

בפוסט זה אנו נבחן פונקציונליות של Selenium WebDriver הנותנת לנו את האפשרות לדווח ללוגים או לדוחות של תוצאות הריצה בצורה נקייה יותר.

נחשוב על זה ככה, אנחנו מריצים כעת כמה מקרה בדיקה עם סלניום, מקרה הבדיקה הזה מכיל בתוכו כמה שלבים (Steps), כמו למשל: ניווט לאתר מסויים, הקלקה על כפתור, הזנת טקסט לתוך שדה וכו’. אנחנו נרצה לדווח לאיזושהי מערכת לוגים \ דוחות על כל הפעולות הללו, אז כמובן אנחנו יכולים לבוא ולשלוח שורת פקודת דיווח אחרי כל שלב ושלב, אבל זה יהיה די פרימיטיבי לעשות כן, כי הקוד שיווצר לנו יהיה מנופח ובלתי קריא. לדוגמא כך (הדיווח כאן מיוצג ע”י כתיבה ל-Console):

 

איכס, זה קוד מגעיל. מה עושים ?
ישנם כמה פתרונות אלגנטיים יותר לפתור את כל שיכפולי הקוד הללו (3 שורות קוד הפכו להיות 6 שורות קוד), אציג כאן אחד מהם. הכירו את ה-EventListeners.

 

myadvSelenium20

 

* נא לא להתבלבל עם ה-TestNG Listener שגם הוא מגיע לפתור את אותה הבעיה, אך בפוסט זה אנו נתמקד דווקא בפתרון המובנה של WebDriver

 

ה-EventListener או בשמו המלא: WebDriverEventListener הינו ממשק (Interface) בספריות הקוד של WebDriver והוא מכיל בתוכו (נכון להיום) רשימה של  23 פעולות אשר נועדו לתפוס events (אירועים) שונים, את הרשימה הזו ניתן לראות בדוקומנטציה הרישמית של הפרוייקט.

מושג נוסף אותו אנו צריכים להכיר הינו ה-EventFiringWebDriver.

זוהי מחלקה שעוטפת את האובייקט של ה-WebDriver (איך מחלקה יכולה לעטוף אובייקט ? תראו עוד מעט בדוגמא) והיא נועדה לזרוק events שונים בזמן ריצת התוכנית, למעשה גם ה-EventFiringWebDriver מממשת את ה-WebDriver , שזה אומר שיהיו לה את כל הפונקציונליות של, נגיד ה-ChromeDriver (כמו findElement , getTitle , switchTo וכו’) ובנוסף עוד 2 פעולות: ה-register וה-unregister

פעולת ה-register תאפשר לנו להירשם להאזנה של events ב-WebDriverEventListener ופעולת ה-unregister תספיק את ההאזנה

לסיכום: ה-EventFiringWebDriver זורק events וה-WebDriverEventListener תופס אותם.

את ההירארכיה של הממשקים\מחלקות הללו ניתן לראות כאן:

events

 

 

את המימוש לכך נבצע בכמה שלבים:

1. איתחול אובייקט ה-driver שלנו מסוג WebDriver באופן הרגיל, למשל נאתחל אותו ל-ChromeDriver לעבודה מול דפדפן הגוגל כרום:

 

2. ניצור אובייקט חדש מסוג EventFiringWebDriver – זוהי המחלקה המממשת את ה-WebDriver, נקרא לו driver ונשלח לבנאי שלו את אובייקט ה-chDriver שיצרנו מקודם (או במילים אחרות אנחנו עוטפים את אובייקט ה-driver במחלקה חדשה -EventFiringWebDriver):

 

3. ניצור אובייקט ממחלקה (נקרא לה eventImplementations) בה אנו נממש את כל המתודות של WebDriverEventListener (את המחלקה והמימושים נראה עוד מעט, כעת אנו רק ניצור את האובייקט שלה):

 

4. נבצע כעת רישום של האובייקט מסוג WebDriverEventListener (אותו יצרנו בסעיף הקודם) ע”י קריאה למתודת ה-register (ששייכת כאמור למחלקת EventFiringWebDriver):

 

בואו נראה כעת את המחלקה המממשת את מתודות ה-WebDriverEventListener , המימוש בדוגמא הזו מתייחס כעת לפעולות: beforeClickOn , afterClickOn , beforeNavigateTo , afterNavigateTo , onException afterChangeValueOf (זאת אומרת שהחלטתי לממש רק 6 פעולות מתוך ה-23)

 

טוב, מה זה אומר ? זה אומר שכעת כשאנו נפעיל את ה-driver שלנו, יתבצעו הפעולות הבאות:

לפני כל הקלקה של העכבר יודפס ל-Console הטקסט: Before Clicking On עם שירשור של שם הכפתור

אחרי כל הקלקה של העכבר יודפס ל-Console הטקסט: After Clicking On Element

לפני ניווט לאתר יודפס ל-Console הטקסט: Before Navigate To עם שירשור כתובת האתר

אחרי ניווט לאתר יודפס ל-Console הטקסט: After Navigate To עם שירשור כתובת האתר

אחרי שליחת טקסט לאלמנט (פעולת ה-sendKeys שאנו מכירים) יודפס ל-Console טקסט בהתאם

וברגע שהטסט יכשל ויזרק Exception, תודפס ההודעה של ה-Exception ל-Console

 

עכשיו נותר לנו רק לממש את הכל ביחד תחת מחלקת ה-Tests שלנו, מקרה הבדיקה שלנו הינו: כניסה לאתר ebay , הזנת הערך: GoPro HERO6 בשדה החיפוש ולחיצה על כפתור ה-Search:

 

מאחורי הקלעים התבצעו הפעולות הבאות.

פקודת ה-driver.get זרקה event שנתפס ב-beforeNavigateTo וב-afterNavigateTo (והכתיבה ל-Console הייתה בהתאם)

פקודת ה-sendKeys זרקה event שנתפס ב-afterChangeValueOf (והכתיבה ל-Console הייתה בהתאם)

פקודת ה-click זרקה event שנתפס ב-beforeClickOn וב-afterClickOn (והכתיבה ל-Console הייתה בהתאם)

events1

 

myadvSelenium20

 

ניתן כמובן גם להרחיב את היכולות של הדיווח ובמקום לרשום ל-Console (כי מי באמת רושם לConsole בפרוייקט אוטומציה אמיתי ?) ניתן לכתוב ל-Reporting System ע”י שימוש ב-API חיצוני כמו ה-Allure או ה-ExtentReports, זה אומר שאנו נהיה חייבים לאתחל את האובייקטים של ה-reports בצורה חכמה יותר ממחלקת ה-eventImplementations שלנו.

למשל נוכל לרשת ממחלקה אחרת ה-base או ה-init שם אנו נדאג לאיתחולים של האובייקטים, כך למשל:

ומחלקת ה-init שלנו למשל תוכל להיראות כך (במקרה הזה אני מציג דוגמא לכתיבה לתוך קובץ חיצוני):

 

עכשיו מה לגביי מחלקת ה-Tests שלנו ? האם ככה באמת נכתוב אותה בפרוייקט שלנו ? איפה ה-Page Objects למשל, איפה האבסטרקציה ? או במילים אחרות – האם ה-Event Listeners תומכים בכתיבה נכונה של תשתיות ? התשובה היא ברור שכן. בסופו של דבר נורה איזשהו event , לא משנה מהיכן בקוד או מאיזו מחלקה (של תשתית או של ביזנס).

לדוגמא, אותו מקרה בדיקה שכתבנו מקודם, נוכל לכתוב כך (עם Page Objects) והכתיבות ל-Console עדיין יעבדו כמו קסם:

מחלקת ה-Pages:

 

מחלקת הטסטים:

 

 


 

בשורה התחתונה , עבודה עם Listeners היא אינטליגנטית, נקייה, ופותרת לנו לא מעט כאבי ראש במימושים שונים לדיווחים. מצד שני, כמו שנכתב כבר ישנם כיום מימושים ל-23 פעולות ב-WebDriverEventListener (החל מגרסת 3.10 של סלניום התווספו עוד שניים: beforeSwitchToWindow ו-afterSwitchToWindow) , זה יפה אבל לא מספיק, ישנן עוד פעולות רבות שאין להם מימושים כמו בחירת ערך מתוך Drop Down או גרירת אובייקטים עם Drag N Drop וכו’, זה אומר שלפעולות אלו נצטרך לבצע מימושים משל עצמינו וזה קצת מבאס…

לעמוד הדוקומנטציה של WebDriverEventListener

לעמוד הדוקומנטציה של EventFiringWebDriver

 

 

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

היי, אני לא רובוט *

תגי HTML מותרים: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">