מיכון בדיקות יחידה

מיכון בדיקות יחידה (באנגלית: Automatic Unit Testing) הוא תת-ענף של בדיקות יחידה בהנדסת תוכנה. המיכון (אוטומציה) מתבטא ביצירה של הבדיקות והרצתן באופן אוטומטי. השימוש באוטומציה נועד להקל על מפתח התוכנה, על בודק התוכנה, ויכול לחסוך לחברת התוכנה משאבים רבים. בדיקות יחידה נועדו לבדוק את הרכיבים הקטנים ביותר במערכת הניתנים לבדיקה (מודול). כתוצאה מכך, במערכות גדולות ייתכנו מאות, אלפי, ואף עשרות אלפי בדיקות יחידה. שימוש בטכניקות אוטומטיות מאפשר יצירה מהירה של כמויות גדולות של בדיקות והרצתן, בהשקעה מינימלית של זמן, כסף, ומשאבים נוספים. שימוש באוטומציה יכול לעזור לכותבי הבדיקות לייצר בדיקות טובות יותר. תוכנות אוטומטיות יכולות לבדוק כיסויים של חלקי קוד באמצעות מדדי כיסוי ולוודא שלא נשארו חלקים ללא בדיקה, או שקיימות בדיקות כפולות שניתן לוותר עליהן, ובכך לייעל את מערך בדיקות היחידה (Test suite). שימוש באוטומציה לבדיקות יחידה הוא חיוני במיוחד במתודולוגית TDD, עקב שימוש נרחב בבדיקות יחידה. לרוב כותבים את בדיקות היחידה לפני כתיבת הקוד, כך שכל פעם נכתבת בדיקה אחת, ואז מתבצע Refactoring, כך שהבדיקה החדשה והבדיקות הקודמות עוברות, וחוזר חלילה. איטרציות אלו מחייבות יכולת יצירה והרצה של הבדיקות בצורה מהירה ויעילה, והכלים האוטומטיים מאפשרים זאת. במקרים בהם כמות בדיקות היחידה היא קטנה יחסית, או שיש דרישות לבדיקות ספציפיות יותר, שימוש בטכניקות אוטומטיות ליצירת בדיקות היחידה עלול לדרוש השקעה מיותרת. במקרים בהם יש צורך להריץ את בדיקות היחידה מספר בודד של פעמים, הכנת הסביבה לריצה אוטומטית עלולה לקחת יותר משאבים מהרצה ידנית של ריצות אלו. ניתן לסווג את טכניקות האוטומציה לפי כמה קטגוריות מרכזיות: סביבת פיתוח: תוכנות סביבה המסייעות ליצור ולהריץ בדיקות יחידה באופן אוטומטי יצירה: יצירת בדיקות יחידה שונות באופן אוטומטי, או על ידי הגדרות בסיסיות בחירה: בחירה אוטומטית של בדיקות יחידה מתוך קבוצה קיימת (בדרך כלל נוצרה גם היא באופן אוטומטי) תיעדוף: בחירה של סדר הרצת הבדיקות. שימושי כאשר יש משאבים מועטים וניתן להריץ רק חלק מהבדיקות. קיימות מספר סביבות פיתוח (לדוגמה JUnit או ויז'ואל סטודיו), המותאמות ליצור שבלוני ואוטומטי של בדיקות יחידה, כמו גם הרצה אוטומטית של הבדיקות וויזואליזציה נוחה של התוצאות. סביבות אלו מאפשרות הרצה של כל בדיקות היחידה, וכלים שונים לאוטומציה הקיימים בשוק יבואו לרוב כתוספת לסביבה קיימת. תהליך היצירה מתחלק לשני חלקים: יצירת רצף של הפעלות של פונקציות מתוך המחלקה הנבדקת (Class Under Test). סיפוק טענת נכונות (Assertion) המאפשרת לקבוע האם תוצאות הבדיקה נכונות או שגויות. קיימות מספר טכניקות ליצירת רצף הקריאות שמהן תורכב הבדיקה. בשיטה זו מייצרים את בדיקות היחידה באופן אקראי, על ידי הגרלת קריאות לפונקציות השונות, או מעבר בין מצבים כאשר ניתן למדל את המחלקה על ידי דיאגרמת מצבים היתרון המרכזי בשיטה זו הוא הפשטות שלה, מה שמאפשר יצירת כמות גדולה של בדיקות יחידה רבות, תוך חיסכון במשאבים. החסרון המרכזי הוא שהאקראיות לא מבטיחה כיסוי של כל המקרים הבעייתיים של התוכנה, וייתכן מאוד שיהיו חלקים שלמים שלא נבדקו. לרוב תשולב שיטה זו עם בחירה של הבדיקות המועדפות, מתוך כמות גדולה שנוצרה. בשיטה זו מייצרים את מקרי הבדיקה על ידי ניתוח סימבולי של הקוד, על ידי שימוש בפסוקים מתמטיים. המטרה היא למצוא עבור כל פונקציה את החלוקה של הקלטים שלה, לפי המסלול בקוד שבה היא עוברת. עבור כל מסלול כזה תיווצר בדיקת יחידה אחת. בדוגמה להלן ניתן לראות פונקציה בסיסית, המקבלת ערך ונכשלת אם הערך הוא 12. בניתוח סמבולי, לכל משתנה קלט מקושר סימבול, ומתקיים מעקב אחרי מצב הסימבולים לאורך הקוד. במקרה הזה Y יקושר לסימבול, והוא יסומן ב-S, בזמן הקריאה, ובהמשך יקושר לערך 2S. בכל פעם שהקוד מגיע לתנאי, כגון y==12, יוגרל הכיוון שבו יתקדם הרצף בקוד ויתווסף אילוץ שיציין איזה מסלול נבחר בקוד. למשל במקרה הזה הוגרל true, והאילוץ יהיה 2S=12. y = read() y = 2 * y if (y == 12) fails() print("OK") כאשר מסתיימת הריצה על כל הקוד, מחושבים הקלטים לפונקציה על ידי פתירת האילוצים שנאספו על הקלטים. מהתוצאה נוצרת בדיקת יחידה אחת. כעת מבוצע התהליך שוב, תוך חישוב מסלול חדש שטרם חושב באיטרציות הקודמות, והאילוצים מעודכנים בהתאם. כך התהליך ממשיך עד שמתקבלות בדיקות יחידה המכסות את כל המסלולים האפשריים בקוד. קיימות מספר טכניקות למציאת הסיפוק המתאים. טכניקה זו מסתמכת על העקרונות: מתודה לא אמורה ליפול עם exception שלא נתפס, וזאת ללא תלות בארגומנטים שסיפקו לה. אי אפשר להניח כלום על תחום הארגומנטים של המתודות. תחת עקרונות אלו, רק מתודות שלא יזרקו exception יספקו את הבדיקה וכאלו שיזרקו לא יספקו. בטכניקה זו בודקים את ה-"Invariant" של האובייקטים ותנאי ההתחלה והסיום של המתודה ורק אם הם נשמרו אז המתודה מספקת. כלומר פונקציה שלא עמדה בחוזה שלה איננה מספקת. טכניקה זו משתייכת לשני החלקים יצירת הרצף ומציאת הסיפוק יחד. בשלב ראשון (שלב ה-Capture) מפעילים את המתודה הנבדקת "מקליטים"/שומרים את תוצאות המתודה ו/או את מצבה של המערכת (state - ערכים במשתנים ובשדות של האובייקטים) לאחר הפעלת המתודה. בשלב שני מופעלת שוב את המתודה ומשווים את תוצאתה ו/או מצב המערכת שמתקבלים הפעם לנתונים שנשמרו בשלב ה-Capture וכל סטייה תחשב לטעות. כלומר רק אם הנתונים יהיו זהים המתודה תספק. טכניקה זו משמשת לרוב ליצירת בדיקות נסיגה כך ששומרים את התוצאות של המתודות בגרסאות קודמות של המערכת וכאשר מעדכנים את המערכת מריצים שוב ומשווים לתוצאות הקודמות. כך ניתן לראות אם יש שינוי בהתנהגות והאם הוכנסו באגים למערכת. טכניקה זו, בניגוד לאחרות, דורשת שהמערכת תהיה זמינה ופועלת. ניתן להשתמש בקריטריונים שונים לצורך בחירת הבדיקות אותן המתכנת או הבודק מעוניינים להריץ מתוך קבוצה גדולה של בדיקות שנוצרו. שימוש מקובל הוא בחירת הבדיקות לפי כיסויים. הרעיון הוא למצוא קבוצת בדיקות (בדרך כלל קטנה ככל הניתן), המכסה את הקוד. למשל: כיסוי כל הפונקציות של המחלקה כיסוי כל הקלטים האפשריים כיסוי כל המסלולים האפשריים בקוד כאשר יש מחסור במשאבים לצורך הרצת כל בדיקות היחידה הרצויות, ניתן ליצור סדר עדיפויות בין הבדיקות, כך שקודם ירוצו הבדיקות החשובות ביותר. באופן דומה לבחירת הבדיקות, גם במקרה של תעדוף ניתן להגדיר קריטריונים שונים של הבדיקות על מנת לקבל תעדוף אוטומטי. JUnit NUnit הבטחת איכות תוכנה בדיקות תוכנה בדיקות נסיגה סרטון הדגמה לכלי המשתמש בcapture & replay ביצירת בדיקות, סרטון באתר יוטיוב http://www.youtube.com/watch?v=KYyj5Dfp8iE http://www.jamtester.com/UnitTestingPaper.pdf http://www.google.co.il/url?sa=t&rct=j&q=&esrc=s&source=web&cd=12&ved=0CF8QFjABOAo&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.99.6030%26rep%3Drep1%26type%3Dpdf&ei=2Y3sT9vtEYLl4QSnqKyWBQ&usg=AFQjCNHzwZbPtaXKIW7fcbRdj1N93iu4WA&sig2=l0f0VvAdCaG8jOz2oW-cVA http://www.phuse.eu/download.aspx?type=cms&docID=573