בתרשים המצורף תוכלו לנווט בין האפשרויות השונות. בכל צומת תוכלו להבין אילו החלטות עליכם לקבל כאשר אתם בוחרים באחת או יותר מהאפשרויות לבדיקת ממשק המשתמש שלכם.
בואו נתחיל:
הגישה הקלאסית: בדיקת רכיבי ממשק משתמש כחלק מבדיקות קצה לקצה (E2E)
במשך זמן רב, ובמידה רבה עדיין עד עכשיו, בדיקות קצה לקצה (E2E) הן הדרך המקובלת לבדיקת ממשק המשתמש. באופן מסורתי הבדיקות הללו הן הקומה העליונה של פירמידת הבדיקות ומשלימות בדיקות יחידה ובדיקות אינטגרציה. בשיטה זו משחזרים את חווית המשתמש בצורה הקרובה ביותר לדרך שבה המשתמשים יפעילו את המערכת.
כדי ליישם בדיקות E2E, נקים סביבה אשר מחקה בצורה הקרובה ביותר את מערכת הייצור שלכם (production). לצורך הבדיקות נקים מסד נתונים אשר מכיל נתוני יסוד הדרושים להקמת המערכת (כגון: משתמשי על (super users), טבלאות המכילות נתוני הגדרה כגון הרשאות, ונתונים התחלתיים לצורך בדיקות כמו מוצרים). כמו כן נקים שרת, או מספר שרתים (micro services) שמאפשרים ביצוע של רוב התהליכים במערכת. על מנת לדמות את פעולות המשתמש בתרחישי שימוש אמיתי נשתמש בכלי שמאפשרים אוטומציה של הדפדפן, כאשר הכלים הפופולריים הם Selenium, Playwright, או Cypress.
היתרון המרכזי של בדיקות E2E הוא שהן מקיפות מאוד. הן מאמתות את כל תהליך העבודה ומספקות רמה גבוהה של ביטחון שהמערכת שלך פועלת כנדרש. הבדיקות גם מבטיחות עבודה חלקה של המשתמשים ושאין בעיות ש״נופלות ביו הכיסאות״ - למשל בין ממשק המשתמש לשרת.
אולם השיטה הזו לא חפה מבעיות. ראשית, מדובר בבדיקות שצורכות הרבה זמן פיתוח: בין אם בבניית מצב התחלתי נכון למערכת, הגדרה של נתונים ועד פיתוח של תהליך שלם. אולם גם אחרי שכתבנו את תסריטי הבדיקה, מדובר בבדיקות שדורשות הן משאבי מחשוב יקרים והן זמן ארוך על מנת להריץ אותן. בנוסף, בדיקות אלו תלויות במספר יחסית גדול של רכיבים כך שהן נוטות להיות שבריריות (flaky) ולצרוך זמן רב של תחזוקה. כאשר האפליקציה שלנו גדלה, עלות התחזוקה של בדיקות E2E הופכת למורכבת ועלולה לשמש צוואר בקבוק בתהליכי הפיתוח. לפיכך, יש יתרון ניכר בהרצת בדיקות ממשק משתמש לפני שנריץ את בדיקות הקצה לקצה.
אלטרנטיבה במשקל נוצה: בדיקת קומפוננטות משתמש עם ״חיקוי דפדפן״ (mock browser)
הדרך הפופולרית לפיתוח ממשק משתמש כיום היא בניה של קומפוננטות קטנות שאותן אנחנו מרכיבים כדי לבנות את מסכי האפליקציה. הפריימוורקים הפופולריים לפיתוח ממשק משתמש - React, Vue Angular או Svelte, מבוססים כולם על ממשק משתמש מבוסס קומפוננטות. יחד עם הפריימוורקים האלה התפתחה הטכניקה של בדיקת ממשק המשתמש בצורה קלת משקל. בשיטה הזו לא משתמשים בדפדפן לביצוע הבדיקות ובמקומו משתמשים בספריות אשר רצות ב-JavaScript בסביבת node.js ומדמות את ה-API של הדפדפן. הבדיקות מתמקדות בעיקר בלוגיקה של כל קומפוננטה, במבני הנתונים שהיא מחזיקה ומדמה אינטראקציות בסיסיות עם ה-DOM. כל בדיקה ממוקדת ברכיב בודד ובאינטראקציה בודדת, או לכל היותר במספר קטן של רכיבים ושל אינטראקציות. הבדיקות האלה ישבו בתחתית פירמידת הבדיקות - בדיקות יחידה או לכל היותר בדיקות אינטגרציה, ובמקרים רבים יכתבו על ידי צוות הפיתוח כחלק מתהליך הפיתוח.
על מנת להריץ את הבדיקות האלה נשתמש בכלי ריצה לטסטים כגון vite או jest (בעולם ה-JavaScript) ובספריות של browser mock כגון jsdom או Happy DOM. בנוסף קיימות ספריות עזר כגון Testing Library שמאפשרת קיצורי דרך בזמן כתיבת הבדיקות עבור פעולות שחוזרות על עצמן, כגון חיפוש אלמנטים ב-DOM.
היתרון של הבדיקות האלה הוא בקלות היחסית שלהן. הן נכתבות במהירות ורצות תוך זמן קצר (במאמר מוסגר כדאי להוסיף שכאשר מדובר ב-DOM מורכב יחסית וחישובים מאתגרים אפשר לראות ירידה משמעותית בביצועים). בנוסף, הבדיקות לא דורשות משאבים מרובים - למעשה, כל הבדיקה רצה בתור אפליקציית node.js.
אבל, כידוע, אין ארוחות חינם. החיקוי של הדפדפנים אינו מדמה באופן מדויק את כל ההתנהגות של דפדפן אמיתי, ובוודאי לא של דפדפנים שונים. חיקוי הדפדפן לא מגיש (render) באמת את האלמנטים של ה-DOM, כך שהם לא יכולים להראות את התצוגה הוויזואלית של המערכת. בנוסף, חיקויים של הדפדפנים לעתים קרובות נכשלים כשמדובר בפונקציונליות מיוחדת כמו פעולות canvas או אירועי מחזור חיים של טעינת מדיה, שהם קריטיים עבור יישומי אינטרנט מודרניים רבים.
הפתרון ההיברידי: בדיקת דפי ממשק משתמש עם נתוני כזב ואוטומציית דפדפן
בשיטה זו אנחנו יוצרים איזון בין בדיקות ריאליות של המערכת ובין שליטה שלנו במערכות נוספות. אנחנו נריץ את ממשק המשתמש של האפליקציה בדפדפן אמיתי, אולם נבצע חיקוי של הקריאות לצד השרת. זו שיטה מועדפת כאשר הצוותים רוצים להתמקד בהתנהגות ממשק המשתמש ללא המורכבות של ניהול סביבת צד שרת מלאה.
כדי ליישם את הגישה הזו אנחנו בונים ומריצים את האפליקציה שלנו ומשתמשים בכלים שמאפשרים יירוט של הקריאות לצד השרת והחזרת חיקוי של תשובות. כלי אוטומציה של הדפדפן כגון Playwright או Cypress מאפשרים להקשיב לקריאות ל-API ולהחזיר תשובות ללא צורך לפנות לשרת אמיתי. בנוסף קיימים כלים כמו Mock Service Worker (MSW) שמאפשרים חיקוי של ה-API. כאשר יש לנו תשובות של קריאות השרת, אנחנו משתמשים בכלי הבדיקות והאוטומציה כדי לדמות אינטראקציות משתמש ולתקף את התנהגות המערכת.
שיטה זו מציעה את הטוב משני העולמות. בשימוש בדפדפן אמיתי, המערכת שלנו תתנהג בצורה רגילה. כמו כן, בתהליך הבדיקה זו יש לנו שליטה מלאה בנתונים ה״חוזרים״ מהשרת, כך שאנחנו יכולים לבדוק מקרי קצה כגון - שגיאת שרת, תשובות ריקות של נתונים ובכך אנו יכולים לוודא שהמערכת שלנו תדע לפעול נכון גם במקרים אלו.
יש מספר אתגרים עיקריים בגישה הזו. ראשית, היא דורשת שימוש במספר כלים - אוטומציה של הדפדפן, הדמיית הקריאות לשרת, ואולי גם כלי לחילול נתוני הדגמה. הגדרה זו דורשת זמן רב ודורשת גם תחזוקה מתמדת בכל פעם שיש שינוי בקריאות ה-API. בנוסף עלולה להיות בעיה בזמן הריצה של הבדיקות, כיוון שלעתים כדי להגיע לדף שאותו אנחנו רוצים לבדוק נאלץ לעשות מספר צעדים (כגון - טעינת המערכת, כניסה למערכת, גישה לדף ההתחלתי ומשם גישה לדף הבדיקות) אשר דורשים זמן ריצה יקר ואינם נותנים הרבה ערך לבדיקה עצמה שאנחנו רוצים להריץ.
טכניקות בידוד: בדיקת רכיבים בדפדפנים אמיתיים
שלוש השיטות הבאות מתמקדות בבדיקה של קומפוננטות בסביבה מבודדת (isolation). השיטות האלה דומות במידה מסוימת לשיטה מספר 2 של בדיקות יחידה / אינטגרציה כיוון שבכל השיטות האלה אנחנו לא נריץ את כל המערכת אלא רכיבים בודדים. בדיקת קומפוננטות בצורה מבודדת מאפשרת להתמקד באלמנטים בודדים של ממשק המשתמש, מווידג'טים קטנים ועד לדפים מלאים, תוך הגשה (rendering) שלהם באופן עצמאי בסביבת דפדפן אמיתית. גישה זו פופולרית מאוד אצל צוותים העובדים עם ספריות רכיבים לשימוש חוזר, אולם ניתן ליישם אותה על כלל רכיבי המערכת.
בשיטה זו נבודד ונגיש כל רכיב בנפרד, תוך שימוש בדפדפן אמיתי. לאחר מכן נוכל להשתמש באוטומציה של הדפדפן על מנת לבדוק אינטראקציות משתמש.
חוזקן של שיטות אלה הוא באפשרות לבדיקה יסודית של כל רכיב ללא המורכבות של כל המערכת. הבדיקה גם מתקפת את הפעולה של כל רכיב בצורה שאינה מושפעת מכלל המערכת, וכך אפשר לוודא שכל רכיב מבצע את הנדרש ממנו ואין זליגה של לוגיקה או תצוגה להקשר של כלל המערכת. שיטות אלו גם מעודדות כתיבה של רכיבים עצמאים ותורמים לאיכות הקוד. הגשה של רכיב בודד הוא מהיר יותר מהרצה והגשה של כל המערכת, מה שיבטיח שהבדיקות תרוצנה מהר יחסית. בנוסף, הגשה של קומפוננטות בדפדפן אמיתי מאפשר לנו לשלב כלים של בדיקות נראות (Visual Regression Tests) אשר יבדקו שרכיבי הממשק שלנו נראים כמו שאנחנו מצפים.
בכל השיטות האלה אנחנו נבחר את הרכיב, או שילוב של מספר רכיבים, שאותם אנחנו רוצים לבדוק ונעביר להן את סט הפרמטרים הנדרש להן לצורך הצגה נכון של הקומפוננטה. נבצע אינטראקציות משתמש על כל רכיב ונוודא שהתצוגה שלו והממשקים שלו לרכיבים אחרים - כגון שינוי state, קריאה ל-API או הפעלה של אירועים (events) מתבצעים בצורה נכונה.
מאידך, הבידוד של הרכיב הוא גם עקב אכילס של הבדיקות. ריצה נכונה של כל רכיב בנפרד לא מעידה בהכרח שהוא יעבוד נכון כאשר יוטמע בתוך המערכת. בנוסף, נדרש מאמץ פיתוח נוסף על מנת להגדיר את סביבת הבידוד. מאמץ הפיתוח הזה יכול להיות משמעותי עבור רכיבים המשולבים עמוק ביישום. גם תחזוקת הרכיבים הנבדקים דורשת מאמץ: ככל שהרכיבים מתפתחים, יש צורך לשמור על עדכניות הגדרת הבידוד.
הכלים המודרניים מאפשרים לנו לבצע את הבדיקה הזו במספר צורות:
בדיקת רכיבים של Cypress ו-Playwright
שני הכלים הפופולריים האלו מציגים שיטה לבדיקות של קומפוננטות. בתחילת הבדיקה נגדיר את הפרמטרים הדרושים להצגה של הקומפוננטה, והכלי יגיש את הקומפוננטה בדפדפן כאשר אנחנו מריצים את הבדיקה.
גישה זו משלבת את היתרונות של בידוד קומפוננטות עם הכוח של כלי בדיקות E2E מוכחים. הרכיבים נבדקים בסביבת דפדפן אמיתית, ומאפשרת זמן ריצה מהיר ויכולות ניפוי באגים חזקות תוך שימוש בכלים שכבר מוטמעים בצוות ומאפשר סביבת בדיקות אחידה.
האתגרים העיקריים נובעים מכך שהכלים האלה הם חדשים יחסית ועדיין סובלים ממחלות ילדות. מפתחים עלולים להיווכח לעיתים קרובות שיכולות בידוד הרכיבים של הכלים לוקות בחסר, כך שהם נאלצים להשקיע משאבים רבים על מנת לבודד את הקומפוננטות או לכתוב מספר רב של קומפוננטות.
פונקציית הבדיקה של Storybook
Storybook הפך לסטנדרט דה פאקטו בתעשייה בכל הקשור לבידוד רכיבים והצגתם בצורה נוחה כולל אפשרות לשנות פרמטרים המועברים לקומפוננטות.
שימוש ב-Storybook הן לפיתוח רכיבים והן לבדיקתם מציע תהליך עבודה אחוד ונוח. הוא מספק את כל היתרונות של בדיקת רכיבים מבודדת תוך שמירה על התהליך כולו בתוך כלי אחד ומוכר. הרצת בדיקות באותה סביבה שבה מפותחים ומוצגים הרכיבים שלך מבטיחים עקביות בתצוגה, ובנוסף השימוש ב-Storybook משמש בתור ״חלון הראווה״ שבו מוצגות הקומפוננטות השונות, כך שאנשים שונים בארגון יכולים לראות את הצד הוויזואלי, כמו גם את הפונקציונליות של כל רכיב במערכת. Storybook מציע אקו סיסטם עשיר לתצוגה של רכיבים בצורה מבודדת, אשר הופכים את השימוש בו למועיל מעבר לביצוע הבדיקות.
בדומה לאפשרויות בדיקת הרכיבים של כלי האוטומציה, גם פה מדובר בגישה שעדיין בחיתוליה וסובלת ממחלות ילדות. מתחת למכסה המנוע, פונקציית הבדיקה של Storybook משתמשת ב-Testing Library שלוקה בחסר בעבודה מול דפדפן אמיתי לעומת כלים כמו Playwright ו-Cypress. בנוסף, תהליך הבדיקות של Storybook מאפשר רק בדיקה יחידה לכל סיפור, כך שנוצר צורך לפתח מספר רב של ״סיפורים״ ורק למטרות בדיקה ומביא לבזבוז של משאבי פיתוח ותחזוקה.
הטוב מכל העולמות: storybook ו-playwright (או Cypress)
גילוי נאות: זוהי שיטת הבדיקות המועדפת עלי לבדיקת קומפוננטות ממשק משתמש.
בשיטה זו משתמשים Storybook להצגת קומפוננטות וב- Playwright להרצת בדיקות וביצוע אוטומציה לדפדפן. כיוון ש- Storybook מציג רכיבים בדפדפן ניתן פשוט לגשת אליהם עם Playwright ולהריץ עליהם מקרי בדיקה.
בשיטת עבודה זו אנחנו משתמשים בחוזקות היחסיות של כל כלי. Storybook ככלי בידוק הקומפוננטות ו- Playwright ככלי הרצת טסטים. בנוסף אנחנו מרוויחים תיעוד של כל קומפוננטות המערכת גם מחוץ להקשר של הטסטים.
החיסרון המרכזי כאן הוא ששילוב של שני כלים דורש עקומת לימוד של כל אחד מהכלים.
לסיכום
סקרתי כאן מגוון שיטות לבדיקת ממשק המשתמש של מערכת אשר חלקן מוכרות יותר ומוכרות פחות.
דגש מיוחד הושם על בדיקות ממשק לקומפוננטות בצורה מבודדת שהן גישות חדשניות למדי וכיוון שכך, עדיין לא התפתחו סביבן תהליכים מיטביים (best practices). צוותים אשר יאמצו את הגישות הללו עלולים לגלות שעליהם להגדיר בעצמם מהן המתודולוגיות ותהליכי העבודה שהם עומדים ליישם בארגון שלהם. יחד עם זאת, לדעתי, הגישות האלה הולכות לתפוס מקום מרכזי יותר ויותר בתהליכי הבדיקות בארגון.
כפי שהוצג, לכל גישה לבדיקת רכיבי ממשק משתמש יש את החוזקות והאתגרים שלה. הבחירה הטובה ביותר תלויה בצרכים הספציפיים שלך, במשאבים ובאופי היישום שלך. יחד עם זאת, אפשר להניח שאסטרטגיית בדיקות מקיפה תכלול שילוב של מספר שיטות הן על ידי צוות הפיתוח והן על ידי צוות האוטומציה. לדוגמה: בדיקת רכיבים מבודדים עם Vitest אשר שמים דגש על הלוגיקה העסקית. בדיקות עם Storybook ו-Playwright אשר בודקות רכיבי ממשק משתמש מהצד הוויזואלי וביצוע אינטראקציות משתמש וכן סדרה של בדיקות E2E אשר תתמקד במסעי משתמש קריטיים לארגון.