פיתוח מונחה-בדיקות

פיתוח מונחה-בדיקות (Test-driven development ובקיצור TDD) היא מתודולוגיית פיתוח תוכנה שבה נכתבת בדיקת יחידה בטרם נכתב הקוד אותו היא בודקת. בפיתוח בשיטה זו בדיקת היחידה נכתבת תמיד באמצעות חבילת תוכנה המיועדת להרצה אוטומטית של בדיקות היחידה (כגון JUnit). בדיקות יחידה לא הוגדרו לראשונה בשיטת פיתוח מונחה-בדיקות, אך בשיטה זו הן נתונות לקבוצת הנחיות מוגדרות היטב.

השיטה זכתה לתפוצה בעיקר כחלק ממתודולוגית Extreme Programming בתחילת שנות ה-2000, אך היא נמצאת בשימוש גם מחוץ להקשר זה. יש הרואים בה כשיטה לעיצוב תוכנה בהנדסת תוכנה.

דרישות קדם
דרישה מרכזית בפיתוח מונחה-בדיקות היא שימוש בחבילת תוכנה תשתיתית ליישום בדיקות יחידה. חבילה זו מורכבת מספריות המצטרפות לקוד הבדיקה ובדרך כלל גם מתוכניות המאפשרות את הרצת הבדיקות שנכתבו באופן אוטומטי. ספריות התוכנה של החבילה יכילו פרוצדורות לבדיקת טענות נכוֹנוּת בקוד הבדיקה (Assertions). כל עוד הפרוצדורות הללו מחזירות אמת, הבדיקה מסיימת בהצלחה וכאשר פרוצדורה כלשהי נכשלת, הבדיקה מסיימת בכישלון.

מחזור הפיתוח

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

יצירת בדיקה
בפיתוח מונחה בדיקות כל הוספת מאפיין חדש לתוכנית מתחילה בכתיבת מקרה בדיקה חדש. לצורך כתיבת מקרה הבדיקה החדש, על המפתח להבין היטב את המפרטים והדרישות הקשורים להוספת המאפיין. בניגוד לשיטה הסטנדרטית, באמצעות שלב ראשוני זה, המפתח ממקד את תשומת לבו להבנה עמוקה יותר של דרישות המאפיין ובכך מונע או מפחית כתיבת קוד שלא תואם לדרישות המבוקשות.

וידוא שהבדיקה החדשה נכשלת
המפתח מריץ את כלל בדיקות היחידה שלו ומוודא שהבדיקה החדשה נכשלת מהסיבה הצפויה שהקוד המתאים עדיין לא מומש. שלב זה נועד כדי לוודא שהבדיקה החדשה אינה מצליחה בטעות.

כתיבת הקוד הנבדק
בשלב זה המפתח כותב את הקוד הפונקציונלי שיגרום לבדיקה לעבור בהצלחה. ההנחיה למפתח היא לכתוב את הקוד הפשוט ביותר שיעבור את הבדיקה, ללא התחשבות בכתיבה יעילה או במצבים עתידיים נוספים שעשויים להתרחש.

וידוא שהבדיקה החדשה מצליחה
המפתח מריץ את כל בדיקות היחידה שלו ומוודא שהבדיקה החדשה עוברת בהצלחה. כמו כן, עליו לוודא שהקוד החדש לא פגע בקוד קודם שנבדק על ידי בדיקות יחידה קודמות. באמצעות המבנה האחיד של הבדיקות והיכולת להריץ אותן באופן אוטומטי מתקבלת יכולת משמעותית של בדיקה לאחור בדומה לבדיקות נסיגה.

ארגון הקוד מחדש
לאחר שהבדיקה עברה בהצלחה, מבצע המפתח ארגון מחדש של הקוד הנבדק (Refactoring) כדי לשפר את ארגונו ויעילותו, במיוחד בהיבט של ביטול כפילויות. לרשות המפתח עומדת בשלב זה היכולת לוודא בביטחון גבוה באמצעות בדיקות היחידה האוטומטיות שארגון הקוד אינו פוגע בפונקציונליות.

רכיבי דמי
הרצת כלל בדיקות היחידה של המפתח או של היישום כולו מחייבת ברוב המקרים שימוש ברכיבי דמי (Mock objects). תפקיד רכיבים אלה הוא להחליף רכיבים אמיתיים שהקוד הנבדק תלוי בהם. ההחלפה מתאפשרת לרוב באמצעות שימוש בממשק משותף שהרכיב האמיתי ורכיב הדמי מממשים. לצורך מימוש רכיבי דמי נעזרים חבילות תוכנה ייעודיות. 

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

יתרונות השיטה
מחקר שבוצע בשנת 2005 מצא כי מפתחים  שהשתמשו במתודולוגיית ה-TDD היו בעלי נטייה להיות יותר יצרניים במהלך עבודתם. כמו כן פותחה השערה שקושרת בין איכות הקוד לבין השימוש בשיטה.
מתכנתים המשתמשים בשיטה זאת בפרויקטים חדשים  דיווחו כי הם מרגישים פחות צורך להשתמש בכלים לניפוי הקוד.
פיתוח בשיטת ה-TDD, בנוסף להיותו כלי שמאפשר אימות ונכונות הקוד, יכול להוביל לעיצוב טוב יותר של הקוד הנכתב. דבר זה נובע מכך ששיטה זאת ממקדת את תשומת לבו של המפתח למקרי השימוש השונים של המערכת לפני כתיבת קוד המימוש.
באמצעות שיטה זאת קיימת סבירות גבוהה יותר  שכל מסלולי הבדיקה כוסו לפחות על ידי מקרה בדיקה אחד, דבר אשר נותן למתכנת רמת אמינות גבוהה יותר של ביצועי הקוד. 
כתיבה בשיטה זאת יכולה להוביל לקוד יותר מודולרי, גמיש ונוח לשינויים.

חסרונות השיטה
 שיטה זאת קשה לשימוש במצבים בהם נדרשת בדיקה פונקציונלית מלאה על מנת לקבוע הצלחה או כישלון של מקרי הבדיקה. דוגמה לכך הם מערכות ממשק משתמש אשר פועלות על בסיס נתונים ומערכות תקשורת בעלי קונפיגורציה מיוחדת.
 הצלחת הטמעת השיטה בארגון תלוי בקבלת התמיכה של הדרג הניהולי. ללא האמונה הארגונית המלאה בכך שהשיטה תגרום לשיפור המוצר, הדרג הניהולי של הארגון יכול לקבל את התחושה שהזמן שהושקע בכתיבת מקרי הבדיקה המקדמים היה בזבוז של זמן.
 בדיקות יחידה הנכתבות בשיטת ה-TDD נכתבות על ידי המתכנת שיממש את קוד הפיתוח ולא על ידי גורם חיצוני אחר, דבר אשר יכול להוביל לכישלון במציאת תקלות הנובעות מטעות של אותו האדם.
 כתיבת קוד הבדיקה מוסיפה על תקורת העומס של ניהול הפרויקט.

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

בשנים 2009–2010 בוצע מחקר מקיף על יעילות השיטה בקרב צוותי פיתוח בחברות IBM ו-Microsoft שהשתמשו בטכניקת ה-TDD. על פי תוצאות המחקר צוותים שעבדו בשיטת פיתוח זו דיווחו כי כמות התקלות בקוד ירדה בין 40 ל-90 אחוזים לעומת צוותים מקבילים שלא השתמשו בשיטה, אולם חשוב לציין כי זמן הפיתוח הראשוני לאחר אימוץ השיטה עלה בין 15 ל-35 אחוזים.

ראו גם
 FIT
 JUnit
 בדיקות יחידה
 פיתוח מונחה התנהגות

קישורים חיצוניים
 כתיבת בדיקות לפני קוד, באתר extremeprogramming.org 
 Test Driven Development 
 A Unit Testing Walkthrough with Visual Studio Team Test 
 Improving Application Quality Using Test-Driven Development

הערות שוליים

בדיקות תוכנה
תכנות