
התיאוריה
לא לחשוב
יוסי: "אני עכשיו סיימתי לכתוב קוד, הוא מאוד יפה ואני מאמין שחשבתי על כל המקרים העמוקים".
הטעות הראשונה שלך יוסי היא, שחשבת. ולחשוב זה אף פעם לא מספיק. אין מה לעשות, אנחנו בני אדם ותמיד נפספס משהו קטן (כן, גם ג'יפיטי מפספס). ולכן כשנסיים לכתוב קוד הדבר הבא שנדרש לעשות, הוא לבחון אותו. ולבחון הכל.
בואו נוסיף קצת צבע, ניקח דוגמא ללוגיקה ולטסטים הנגזרים ממנה.
הדוגמא
לי יש פונקציה שביניתי, היא לוקחת מחיר של מוצר, אחוז הנחה, ומחזירה את מחיר המוצר אחרי ההנחה. אילו בדיקות נוכל לגזור? נחלק אותן לשלושה סוגים.
- בדיקה רגילה- בדיקה שמוודאת הקוד פועל כמצופה תחת קלט סביר.
- בדיקת גבול- בדיקה של מקרי קצה, הקוד מתנהג נכון גם כשאנחנו בדיוק על הגבול או לידו.
- בדיקת שגיאה- בדיקה מה קורה כשנותנים ערכים לא תקינים, ווידוא כי הוא לא נכשל או מתבלגן, אלא מתנהג בצורה צפויה – למשל זורק שגיאה עם הודעה מתאימה.
אז מה יהיו השגיאות שנכתוב לפונקציית ההנחה לפי הסוגים האלו?
- בדיקה רגילה – מחיר 200 ש"ח עם הנחה של 25% צריך להחזיר 150 ש"ח.
- בדיקת גבול – 0% הנחה – מחיר 100 ש"ח והנחה של 0% צריך להחזיר 100 ש"ח.
- בדיקת גבול – 100% הנחה – מחיר 100 ש"ח עם 100% הנחה צריך להחזיר 0 ש"ח.
- בדיקת שגיאה – מחיר שלילי – אם מעבירים מחיר שלילי, למשל -50 ש"ח, צריך לזרוק שגיאה.
- בדיקת שגיאה – אחוז הנחה לא תקין – אם מעבירים אחוז הנחה נמוך מ-0 או גבוה מ-100 (כמו -10% או 150%) צריך לזרוק שגיאה.
אוטומטי
אנחנו כמפתחים, כמובן שנחשוב - מה אני אעשה את כל הטסטים האלו בצורה ידנית? בשביל מה למדתי 3 שנים מדעי המחשב באוניברסיטה? על השאלה למה למדת אין לי תשובה, אבל אנחנו בהחלט יכולים לעשות טסטים אוטומטיים, וכשטסטים האוטומטיים הקסם מתחיל באמת.
האם פעם נתקלתם בסיטואציה שבה אתם נוגעים בקוד ישן ומאוד מסובך ואתם צריכים להוסיף לו פיצר חדש? מכירים את פחד האימים הזה שדפקת בטעות משהו בקוד הזה וכל הפרודקשן יקרוס? כולנו היינו שם. הדרך הכי פשוטה להימנע מזה היא בניית אותם הטסטים האוטומטיים. ברגע שיש לנו טסטים אוטומטיים המכסים את הלוגיקה ואת מקרי הקצה שהקוד אמור לתפוס, אנחנו יכולים להיות בטוחים שכשאנחנו משנים משהו, הוא ממשיך להיות תקין, על ידי זה - שפשוט נריץ אותם ונראה שכולם עוברים.
וכך בעצם טסטים תורמים הרבה לדינמיות של הצוות, בעזרתם לא נמנע מלגעת בקוד תשתית, כי יש לנו את הבטחון שאם אנחנו משנים בו משהו, אנחנו יכולים לוודא שהכל נשאר תקין בלחיצת כפתור - כפתור הרצת הטסטים האוטומטיים.
סוגי הטסטים
ישנם הרבה סוגי טסטים, נלמד עליהם כעת.
לצפייה
אז לסיכום יש לנו,
Unit Tests
- משמש לבדיקת פונקציות בקוד.Component Tests
- משמש לבדיקת האפליקצייה כולה בבידוד משירותים שהיא תלויה בהם.Integration Tests
- משמש לבדיקת החיבוריות של האפליקצייה אל השירותים שהיא תלויה בהם.System/End-To-End Tests
- משמש לבדיקת המערכת בכללותה.
כשבנה יוניט טסטים בסי שארפ הם יהיו באותו הפרויקט, עם הקוד עצמו. אך השאר יהיו במנותק, כלומר בפרויקטים ייעודיים. שכן הם צריכים לתשאל את האפליקצייה מבחוץ.
העבודה עם קיואיי
יוסי: "כל כך הרבה סוגי טסטים לכל כך הרבה מקרים... רק ללתחזק את זה צריך בן אדם משל עצמו".

ובכן יוסי, עכשיו אתה צודק לחלוטין, ובשביל זה אלוהים ברא את הקיואיי! בכל מקום רוחב האחריות שלו שונה, אך לצורך העניין נתייחס אליו כאן כקיואיי + מפתח אוטומציה.
תצורת העבודה האידיאלית
הקיואיי אמור להיות אחראי על טסטים מרמת הקומפוננט ומעלה כולל. יוניט טסטים הם תמיד באחריות המפתח עצמו. אז, בשביל שהקיואיי יוכל בכלל להבין איך הלוגיקה של האפליקצייה עובדת, דרוש שקודם כל נבנה תיעוד על מפורט על הלוגיקה של האפליקצייה, ורק אז הקיואיי יוכל להתחיל את עבודתו, שכן הוא לא אמור להיכנס לנו לקוד. אספר שמניסיוני שלב זה מאוד חשוב, שכן רק מקריאת התיעוד קיואיי כבר הצליח למצוא לי באגים לוגיים.
אמנם בעולם אידיאלי הקיואיי יוכל לייצר טסטים אוטומטיים להכל, אך במקרים של דחיפות לא תמיד דבר זה יינתן. ואז הקיו איי יידרש לבצע את הבדיקות באופן ידני. במקרה כזה גם הוא יידרש לתעדף את העבודה שלו ככה שילך תחילה על בדיקות רגילות ולא גבול או שגיאה, כדי לוודא ראשית את התקינות בסיסית של המערכת. בנוסף זהו תפקידו של הקיואיי לבצע בדיקות תקינות לפני כל הורדת גרסה לפרודקשן.
הפרקטיקה
הבסיס
אוקיי אז יאללה, בואו נכתוב טסט. איך נעשה זאת?
לצפייה
אז כמה נושאים מהסרטון שאני אדגיש שוב הם:
- עקרון ה
AAA
- כל טסט נחלק לשלושה חלקים,Assert
- סידור הנתונים איתם הטסט אמור לעבוד.Act
- הפעלת הפעולה, כמעט תמיד שורה אחת.Assert
- מוודא שמה שציפינו שיקרה קרה.
TestCases
- כלי לייעול העוזר לנו לחסוך בקוד ולבדוק כמה קלטים שונים בטסט אחד. הטסט יתפצל לכמה שונים אך בפועל אותו הקוד ישמש בכולם.
רגע אוקיי אז כל זה יוניט טסטים, אז איך כותבים קומפוננט וכו'? התשובה היא שתצורת הכתיבה היא זהה בכולם, פשוט קומפוננט טסט או סיסטם ישלחו הודעה לשירות בHTTP
וכו' במקום לפנות לפונקציה מסויימת.
הלא בסיס
שמות הטסטים

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