ישנם שלושה סוגים בסיסיים של בדיקות בפרונט-אנד:
- Unit – בדיקת הפונקציונליות של הקוד.
האם הקוד מתפקד כצפוי? במקרה זה בודקים את המחלקות, כל אחת בפני עצמה.
אם יש תלות בגורם חיצוני, מדמים, "ממקמקים" אותו.
- Integration – בודקת האם רכיבים במערכת מתפקדים אחד עם השני כצפוי.
- E2E – בודקת האם המערכת כולה מתפקדת כצפוי.
בעוד שני הסוגים האחרונים של הבדיקות בודקים את הממשק עצמו, הסוג הראשון בודק את הקוד ישירות, בו אנחנו עומדים להתמקד הפעם.
קארמה? ג'סמין?
ממה בנוי יוניט טסט בעצם?
הרי הקוד שלנו מאפשר באופן עקרוני לזרוק שגיאות באופן יזום אם משהו לא תקין.
אבל כאשר רוצים להריץ בדיקות על מערכת שלמה, רוצים גם שהבדיקות האלה יהיו אחידות באופי ובנראות שלהן.
לשם כך קיימות שתי ספריות שאחראיות על שני היבטים של הרצת בדיקות באנגולר:
הראשונה, Jasmine, אחראית על הקוד שמניח הנחות לגבי הקוד שלכם ומאמת את המציאות מולן.
השניה, Karma, אחראית על הרצת הבדיקות בצורה מסודרת והצגת התוצאות על המסך.
ג'סמין מכילה בתוכה אוסף של פקודות שמהוות מבנה קבוע ואחיד לבדיקה במסגרת של אנגולר. אנחנו נראה דוגמא שלמה בהמשך.
אבל גם אם יש לנו בסיס קוד שמסוגל לעשות משהו, עדיין צריך דרך להריץ אותו. ועדיין יש ערך מוסף להציג אותו על המסך בצורה נוחה ומסודרת.
כאן נכנסת קארמה לתמונה. קארמה רצה על כל החלקים בבסיס הקוד שיש להם קובץ בדיקות תואם. את קבצי הבדיקה האלה אתם תזהו לפי סיומת spec.ts.
קארמה מריצה את קוד הבדיקה, שולפת את התוצאות ומציגה אותן בדפדפן בצורה מסודרת. בתור ערך מוסף, קארמה גם יודעת לעקוב אחרי שינויים בקוד הבדיקות ולהריץ הכל מחדש אם יש שינויים שנשמרו.
מתחילים לבדוק
בשביל להיכנס לעניינים לא צריך יותר מאשר לייצר פרוייקט אנגולר בסיסי.
הפרוייקט מגיע עם קומפוננטה אחת, אשר מוצמד אליה קובץ טסט מוכן עם כל הבדיקות הנדרשות.
בתוך הספרייה בה נרצה לייצר את הפרוייקט שלנו נקליד:
ng new my-test
(שם הפרויקט שלנו הוא my-test)
לאחר יצירת הפרויקט כדאי לפתוח אותו עם עורך, IDE, כגון VSCode.
שימו לב בקובץ package.json לשורה הבאה:
"test": "ng test"
פקודה זו תריץ את כל הבדיקות הפעילות במערכת.
אבל רגע, איך בעצם המערכת יודעת מה להריץ?
שימו לב שלצד הקומפוננטה הבודדת שנוצרה יופיע קובץ טסט מקביל.
קארמה תבדוק את קובץ ההגדרות (test.ts) ותפעיל כל קובץ שמתאים לתבנית.
לכן שימו לב לדרך שבה אתם מייצרים רכיבים באנגולר. בד"כ יוצרים קובץ חדש וזאת דרך פשוט מצויינת לשכוח לצרף לו קובץ בדיקות!
בגלל זה אני ממליץ מאד להקפיד לייצר קבצים בעזרת ה-schematics של אנגולר במקום ישירות.
זה גם מאד נוח, כי באופן זה לא רק שהקובץ ייווצר, אלא גם התכולה הבסיסית שלו.
אם נריץ את הפקודה נקבל כל מיני הודעות בטרמינל, אבל השורה התחתונה היא בעיקר מה שמעניין אותנו כרגע, וכן החלון שייפתח. אם הכל בסדר, אנחנו אמורים לראות שכל 3 הבדיקות עברו בשלום.
החלון אמור להיראות דומה לזה:
אתם יכולים לראות את תוצאות הבדיקה בצורה מסודרת.
לא רק כמה עברו (לא נכשלו), אלא גם מה ההנחות שנבדקו בזמן הריצה.
קובץ הבדיקה של הקומפוננטה אמור להיראות ככה:
למעשה המבנה הכללי בנוי כך:
- בחלק הראשון מופיעה כותרת הבדיקה. תוכלו לראות אותה בראש התוצאות.
- בחלק השני נמצאות ההגדרות שיופעלו לפני כל בדיקה ובדיקה. במקרה הזה מדובר על יצירה סינתטית של הקומפוננטה, שכן הבדיקה נעשית מחוץ לאנגולר בפועל.
- בחלק השלישי אפשר לראות את הבדיקות עצמן. לכל בדיקה יש כותרת משל עצמה ופונקציה שבה מתבצעת ההנחה לגבי ערך מסויים במערכת.
שוברים את הבדיקות
ברור לנו שבדיקות יכולות לעבור, אבל גם להיכשל, אם משהו מהנחות המוצא שלנו שגוי, או השתנה עם הזמן.
בואו נשבור את כל אחת מהבדיקות באופן שונה וכך נלמד עוד משהו על ג'סמין והדרך בה היא בודקת.
הבדיקה הראשונה מניחה שהקומפוננטה נוצרה, כלומר יש לה ערך כלשהו. בואו נניח את ההיפך.
expect(app).toBeFalsy();
הבדיקה השניה מניחה שמשתנה מכיל טקסט מסויים. בואו נבדוק שהוא לא מכיל את הטקסט הזה.
expect(app.title).not.toEqual('my-test');
הבדיקה השלישית מניחה שהטקסט בדף יכיל טקסט מסויים. בואו נניח שהוא מכיל טקסט אחר.
expect(compiled.querySelector('.content span').textContent).toContain('my-test app is not running!');
עכשיו שימרו את הקובץ ותראו שהבדיקות רצות מחדש באופן אוטומטי, שזה נוח מאד כמובן.
מה קיבלנו?
כצפוי כל הבדיקות נכשלו.
לסיכום
במאמר הנ"ל סקרתי והסברתי מה זה בעצם Unit Testing / UTs באנגולר ועל הספריות שמאחוריהן.
יש נושאים נוספים שהם מעבר למבוא זה, כגון איך בודקים קוד אסינכרוני, איך ממקמקים תלויות ועוד, אבל הם מחוץ לתחום של מאמר זה ונכתוב על כך בהמשך.
בשלב זה אמור להיות לכם בסיס מספיק בשביל להתחיל לבנות בדיקות בסיסיות ולהתחיל לכסות את הקוד שלכם.
בהצלחה,
גיל שטיינר.