הסרטון הזה עוסק בשני סוגים של כלים שאנחנו משתמשים בהם כדי לבדוק קוד. כלים פורמליים הם צרים ומדויקים: הם מפעילים כללים קבועים על תנאים מוגדרים. בקבוצה הזאת נמצאים טסטים, בודקי טיפוסים ולינטרים. הכלי המעורפל הוא סוכן הקוד עצמו, כשמשתמשים בו כסוקר. הוא יכול לענות על שאלות רחבות, אבל חוות הדעת שלו עשויה להשתנות אפילו על אותו קוד. נראה איך בדיקות מאפשרות לסוכן לכתוב, להריץ, לקרוא כישלון ולנסות שוב, ומתי שווה להשקיע בהקמה של הלולאה הזאת.
טסטים, טיפוסים ולינטרים פותחו כדי לעזור לאנשים לכתוב תוכנה. אנשים עושים טעויות, שוכחים שינויים קודמים, ולא מסוגלים להחזיק בראש בסיס קוד שלם. אם עוד לא עבדתם עם לינטר, זו תוכנית שקוראת את הקוד שלכם בלי להריץ אותו ומדווחת על דפוסים שהם חוקיים אבל חשודים, למשל import שאף אחד לא משתמש בו.
גם סוכנים עושים טעויות ומאבדים מעקב אחרי שינויים קודמים. גם כשסוכן מאוד טוב במשימה מסוימת, אנחנו צריכים דרך לתפוס את השגיאות שהוא עושה.
אז בדיקות שתופסות טעויות עוזרות גם לאנשים וגם לסוכנים, כי שניהם עושים טעויות שבדיקה יכולה למצוא.
עכשיו בואו נסתכל איך נגמר סשן רגיל. הסוכן כותב קצת קוד ואומר לכם שהוא סיים. אנחנו עדיין צריכים לבדוק שהשינוי עשה את מה שביקשנו.
מועמד אחד לתפקיד הוא אתם. אתם מריצים את התוכנית, או קוראים את ה-diff, ומבינים אם השינוי עשה את מה שביקשתם. זה עולה לכם בתשומת לב על כל שינוי ושינוי.
אחר כך אתם אומרים מה לא בסדר, והסוכן מנסה שוב. זאת הלולאה שרוב האנשים נמצאים בה ביום הראשון שלהם עם סוכן.
כל סיבוב של הלולאה הזאת מחכה לבן אדם. היא רצה במהירות אנושית, ונעצרת ברגע שאתם מפנים את המבט.
הנה הלולאה שהיינו מעדיפים. היא מתחילה באותו אופן, הסוכן כותב קצת קוד.
אחר כך היא מריצה בדיקה, למשל מערך הטסטים, בודק הטיפוסים או הלינטר. הבדיקה צריכה להחזיר תוצאה שהסוכן יכול להשתמש בה בלי לחכות שאתם תבדקו את התוכנית.
אם הבדיקה נכשלת, הסוכן קורא את הכישלון. כישלון טוב אומר איזה מקרה נשבר ומה היה אמור לקרות, הרבה יותר ספציפי מבן אדם שאומר שזה לא עובד.
הסוכן עורך את הקוד ומריץ את הבדיקה שוב. לפעמים הבדיקה עצמה שגויה, אז השוו כישלון מפתיע מול הדרישה לפני שאתם משנים את הקוד או את הטסט. אם אותה בדיקה ממשיכה להיכשל, או שהדרישה עצמה לא ברורה, הסוכן צריך לעצור ולשאול אתכם במקום להמשיך לנסות.
כשהבדיקה עוברת, הסוכן יכול להביא לכם את השינוי יחד עם התוצאה הזאת. הוא יכול לחזור על הבדיקה והתיקון בין הסקירות שלכם, ואז אתם סוקרים אם העבודה עונה על המשימה. הבדיקה לא הופכת את המודל לחכם יותר. היא אומרת לסוכן מה נכשל בזמן שהשינוי עדיין טרי, במקום להשאיר את הפגם לסשן דיבוג מאוחר יותר.
לולאת הבדיקה צריכה משוב שהסוכן יכול לסמוך עליו כשהוא מחליט מה לתקן. בדיקה דטרמיניסטית מחזירה את אותה תשובה לאותו קלט ובאותם תנאים. התנאים האלה כוללים כל דבר שהבדיקה תלויה בו מלבד הקוד, כמו השעון, מספרים אקראיים או שירות חיצוני. טסט שקורא את השעה הנוכחית או פונה לשרת אמיתי יכול לשנות את התשובה שלו גם כשהקוד נשאר אותו דבר.
טסטים, בודקי טיפוסים, לינטרים וקומפיילרים עובדים כולם כך. אנחנו קוראים להם כלים פורמליים. פורמלי כאן לא אומר הוכחה מתמטית. הכוונה היא שתוכנה מפעילה כללים קבועים, ומזה נובעות שתי תכונות. הם צרים: הם בודקים רק את התנאים שנתנו להם. והם מדויקים: כל תנאי עובר או נכשל, בלי שיקול דעת באמצע.
כלי פורמלי מפעיל את הכללים שלו בלי קשר לכמה ביטחון הסוכן מפגין כשהוא מתאר את העבודה שלו. זה נותן ללולאה תוצאה יציבה לעבוד איתה.
הכלי המעורפל שהזכרנו קודם הוא סוכן הקוד עצמו, או מודל השפה שמאחוריו, כשמבקשים ממנו לסקור את הקוד. הוא יכול לענות כמעט על כל שאלה שתשאלו על הקוד, ולכן הוא רחב.
זכרו שמודל שפה הוא סטוכסטי. הוא דוגם את הפלט שלו, ולכן אם שואלים את אותה שאלה על אותו קוד כמה פעמים, אפשר לקבל תשובות שונות. כאן הקוד לא השתנה בכלל. ריצה אחת אומרת שהוא תקין, ריצה אחרת מוצאת מקרה חסר, ושלישית רק מציעה שם חדש.
בנוסף, הסוכן לא בהכרח קורא הכול או בודק הכול. הוא יכול לדלג על קובץ חשוב, או לטעון שמקרה נבדק כשלא הורץ כלום.
אז חוות הדעת של הסוכן יכולה להשתנות גם כשהקוד נשאר אותו דבר. לכן הוא שימושי כסוקר, אבל לא כבדיקה יציבה בשביל הלולאה.
שני סוגי הכלים עוזרים בשאלות שונות. משמאל נמצאים תנאים שניסחנו כבדיקות: התנהגות צפויה, טיפוסים תואמים, וכללים של הפרויקט. מימין נמצאות שאלות סקירה רחבות יותר: האם השמות ברורים, האם המבנה הגיוני, או האם חסר מקרה חשוב.
הכלי הפורמלי בודק בדיוק את התנאים שנתתם לו, ולא מכסה שום דבר מעבר לזה. מערך טסטים שבודק פלטים צפויים לא יגיד לכם אם התכנון מבלבל.
סוכן הקוד, כשהוא משמש ככלי המעורפל, מכסה את שני סוגי השאלות, ובגלל זה אנחנו רוצים אותו. אבל התשובה שלו יכולה להיות שגויה גם במקומות שבהם הייתה זמינה בדיקה קבועה. הרוחב שלו מועיל כשהוא מעלה בעיה שלא חשבתם לבדוק, כמו הרשימה הריקה שאחת הסקירות מצאה. ברגע שהחלטתם מה רשימה ריקה צריכה להחזיר, התוצאה הצפויה הזאת יכולה להפוך לטסט.
כשאפשר לנסח תנאי בצורה מדויקת, תבדקו אותו עם כלי דטרמיניסטי במקום לשאול את הסוכן. הבדיקה נותנת את אותה תשובה בכל ריצה. היא גם זולה יותר. הרצה של מערך טסטים מקומי לוקחת שניות של זמן מחשב, ואילו על סקירה של מודל משלמים בטוקנים שהוא מייצר, וזה הרבה יותר יקר. אז תריצו קודם את הבדיקות הדטרמיניסטיות, ותשאלו את הסוכן על מה שהן משאירות פתוח, כמו שמות, מבנה ומקרים חסרים.
סקירה של שינוי דורשת את תשומת הלב שלכם בכל פעם מחדש. מה שלמדתם עוזר בסקירה הבאה, אבל עדיין תצטרכו לבדוק את העבודה החדשה.
בבדיקה אוטומטית אפשר להשתמש שוב ושוב. אחרי שכתבתם אותה, היא יכולה לרוץ אחרי כל שינוי, לרוב תוך כמה שניות. אתם מתחזקים אותה כשהדרישה או הקוד מסביב משתנים.
בדיקה לשימוש חוזר מצמצמת את מה שצריך לאמת ידנית אחרי כל שינוי. מחליטים פעם אחת מה חשוב, ומשם הבדיקה ממשיכה לבדוק את זה.
טסטים הם לא בחינם. כשמבקשים מהסוכן לכתוב אותם, יש לו יותר עבודה, וזה עולה יותר טוקנים ויותר זמן בכל משימה.
טסטים הם גם עוד קוד שצריך לתחזק. כשדרישה משתנה, גם הטסטים שמתארים אותה צריכים להשתנות.
את העלויות האלה קל לראות. התמורה מגיעה בשני חלקים. טסט יכול למצוא פגם בשינוי שאתם עושים עכשיו. ומכיוון שטסטים מצטברים, הוא ממשיך לבדוק את ההתנהגות הזאת בכל שינוי מאוחר יותר.
קחו אפליקציית משימות קטנה שמקבלת שלושה פיצ'רים: הוספת פריטים, סימון שלהם כהושלמו, ושמירה וטעינה של הרשימה. אחרי שלושתם, הרצה אחת של מערך הטסטים בודקת כל אחד מהם, כי הטסטים של הפיצ'רים הקודמים נשארים במאגר.
שינוי יכול לשבור פיצ'ר שעבד קודם. כישלון כזה נקרא רגרסיה. כאן, הוספת השמירה והטעינה שברה את הוספת הפריטים, והטסטים של ההוספה תופסים את זה. אף אחד לא צריך לבדוק שוב ידנית את הפיצ'רים הקודמים. כשהטסטים האלה עוברים, יש לכם ביטחון מסוים שמה שעבד קודם עדיין עובד. אותו דבר נכון לבאג שתיקנתם. תשמרו את הטסט ששחזר אותו, ואם הבאג יחזור, הטסט הזה ייכשל שוב.
הטסטים הישנים לא רואים הכול. פיצ'ר חדש יכול להשפיע על פיצ'ר קודם בדרכים שהטסטים האלה אף פעם לא ניסו. סימון פריט כהושלם עובד, ושמירה וטעינה של רשימה עובדות. עכשיו סמנו פריט כהושלם, שמרו את הרשימה וטענו אותה לאפליקציה חדשה. בחרו במסנן Active, והפריט שהושלם מופיע בין הפעילים, כי בצורה השמורה לא נרשם אם כל פריט הושלם. אף טסט קיים לא עשה את הצעדים האלה יחד, ולכן השילוב הזה צריך טסט משלו.
טסטים ישנים תופסים רגרסיות בהתנהגות שהם בודקים. הם לא בודקים שילובים שהם אף פעם לא מפעילים, אז כשפיצ'רים חולקים מצב, תבדקו אותם יחד ותשמרו את הטסט הזה.
מערך בדיקות נותן יותר מסתם הגנה מפני רגרסיות. ראשית, סשן חדש יכול להריץ את מערך הטסטים כדי לבדוק דרישות שנקבעו בסשנים קודמים. הבדיקות האלה נשארות במאגר גם כשהשיחה כבר איננה.
שנית, בדיקות שאפשר להריץ שוב ושוב מצמצמות את כמות ההתנהגות שצריך לאמת ידנית כשסוקרים שינוי.
יש מקרה שבו בדיקות נעשות חשובות במיוחד. סוכן יכתוב לכם תוכנית בשפה שמעולם לא השתמשתם בה, אבל אתם מאבדים את היכולת לסקור אותה בשטף. עדיין אפשר לנסח התנהגות צפויה ולהריץ טסטים בזמן שלומדים מספיק כדי לקרוא את הקוד או משיגים עזרה בסקירה.
שום דבר מזה לא אומר שלכל פרויקט צריכים להיות טסטים. תחשבו על זה כעל רצף של שימוש חוזר. בקצה אחד, אב-טיפוס שאתם מוחקים ביום חמישי. בקצה השני, מאגר ששלושה אנשים עושים אליו push כל יום.
בדיקות עולות בהקמה, בטוקנים, בזמן ריצה ובתחזוקה. הן קונות אמינות ומאפשרות לסוכן לעשות יותר עבודה בלי השגחה. אב-טיפוס קצר-חיים מריץ את הבדיקות שלו רק כמה פעמים לפני שמוחקים אותו. במאגר משותף, כל שינוי מריץ אותן מחדש.
שאלו אם לקוד הזה יש עתיד: האם אתם או מישהו אחר תמשיכו לשנות אותו? ככל שבדיקה מועילה תרוץ יותר פעמים, כך יש יותר סיבה לבנות אותה. קחו בחשבון גם את המחיר של טעות דווקא במשימה הזאת. סקריפט חד-פעמי שממיר נתונים חשובים אולי ירוץ רק פעם אחת, אבל טעות שם יקרה, אז עדיין מגיעה לו בדיקה קפדנית.
כלים פורמליים הם צרים ומדויקים לגבי תנאים שהוגדרו מראש. כלים מעורפלים הם רחבים, אבל השיפוט שלהם יכול להשתנות. ביחד הם מכסים את הבדיקות שאנחנו יכולים להגדיר ואת השאלות הרחבות יותר שעדיין צריך לסקור.
בדיקות שאתם שומרים ממשיכות לבדוק דרישות קודמות אחרי כל שינוי, כך שאף אחד לא צריך לבדוק אותן שוב ידנית. המגבלה שלהן היא מה שהן אף פעם לא מפעילות. כשפיצ'רים חולקים מצב, השילוב שלהם צריך טסט משלו.
יש שלושה סוגים נפוצים של בדיקות פורמליות. טסטים משווים התנהגות מול ציפיות. טיפוסים בודקים שהערכים מתאימים למקום שבו משתמשים בהם. לינטרים בודקים דפוסים נבחרים וכללים של הפרויקט.
בהתחלה, הסוכן אמר שהוא סיים, ואתם הייתם צריכים לבדוק כל שינוי בעצמכם. כשיש בדיקות, הסוכן יכול להריץ אותן, לקרוא מה נכשל, לתקן, ולהביא לכם שינוי שכבר עובר אותן. ואז הסקירה שלכם יכולה להתמקד במה שהבדיקות לא מכסות.
בהצלחה עם הבדיקות. נתראה בסרטון הבא.