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

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה לניווט קפיצה לחיפוש

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

יתרונות שימוש באוטומציה לבדיקות יחידה[עריכת קוד מקור | עריכה]

  • בדיקות יחידה נועדו לבדוק את הרכיבים הקטנים ביותר במערכת הניתנים לבדיקה (מודול). כתוצאה מכך, במערכות גדולות ייתכנו מאות, אלפי, ואף עשרות אלפי בדיקות יחידה. שימוש בטכניקות אוטומטיות מאפשר יצירה מהירה של כמויות גדולות של בדיקות והרצתן, בהשקעה מינימלית של זמן, כסף, ומשאבים נוספים.
  • שימוש באוטומציה יכול לעזור לכותבי הבדיקות לייצר בדיקות טובות יותר. תוכנות אוטומטיות יכולות לבדוק כיסויים של חלקי קוד באמצעות מדדי כיסוי ולוודא שלא נשארו חלקים ללא בדיקה, או שקיימות בדיקות כפולות שניתן לוותר עליהן, ובכך לייעל את מערך בדיקות היחידה (Test suite).
  • שימוש באוטומציה לבדיקות יחידה הוא חיוני במיוחד במתודולוגית TDD, עקב שימוש נרחב בבדיקות יחידה. לרוב כותבים את בדיקות היחידה לפני כתיבת הקוד, כך שכל פעם נכתבת בדיקה אחת, ואז מתבצע Refactoring, כך שהבדיקה החדשה והבדיקות הקודמות עוברות, וחוזר חלילה. איטרציות אלו מחייבות יכולת יצירה והרצה של הבדיקות בצורה מהירה ויעילה, והכלים האוטומטיים מאפשרים זאת.

מגבלות השימוש באוטומציה לבדיקות יחידה[עריכת קוד מקור | עריכה]

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

סיווג טכניקות וכלי האוטומציה[עריכת קוד מקור | עריכה]

ניתן לסווג את טכניקות האוטומציה לפי כמה קטגוריות מרכזיות:

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

סביבת פיתוח[עריכת קוד מקור | עריכה]

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

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

תמונת מסך של JUnit. הפס הירוק בראש המסך מסמן שכל הבדיקות שהורצו עברו

יצירת בדיקות יחידה[עריכת קוד מקור | עריכה]

תהליך היצירה מתחלק לשני חלקים:

  • יצירת רצף של הפעלות של פונקציות מתוך המחלקה הנבדקת (Class Under Test).
  • סיפוק טענת נכונות (Assertion) המאפשרת לקבוע האם תוצאות הבדיקה נכונות או שגויות.

יצירת הרצף[עריכת קוד מקור | עריכה]

קיימות מספר טכניקות ליצירת רצף הקריאות שמהן תורכב הבדיקה.

Random[עריכת קוד מקור | עריכה]

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

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

Symbolic[עריכת קוד מקור | עריכה]

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

דוגמה לניתוח סימבולי[עריכת קוד מקור | עריכה]

בדוגמה להלן ניתן לראות פונקציה בסיסית, המקבלת ערך ונכשלת אם הערך הוא 12. בניתוח סמבולי, לכל משתנה קלט מקושר סימבול, ומתקיים מעקב אחרי מצב הסימבולים לאורך הקוד. במקרה הזה Y יקושר לסימבול, והוא יסומן ב-S, בזמן הקריאה, ובהמשך יקושר לערך 2S. בכל פעם שהקוד מגיע לתנאי, כגון y==12, יוגרל הכיוון שבו יתקדם הרצף בקוד ויתווסף אילוץ שיציין איזה מסלול נבחר בקוד. למשל במקרה הזה הוגרל true, והאילוץ יהיה 2S=12.

y = read()
y = 2 * y
if (y == 12)
 fails()
print("OK")

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

סיפוק הבדיקה (Assertion)[עריכת קוד מקור | עריכה]

קיימות מספר טכניקות למציאת הסיפוק המתאים.

Uncaught Exceptions[עריכת קוד מקור | עריכה]

טכניקה זו מסתמכת על העקרונות:

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

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

Operation Model[עריכת קוד מקור | עריכה]

בטכניקה זו בודקים את ה-"Invariant" של האובייקטים ותנאי ההתחלה והסיום של המתודה ורק אם הם נשמרו אז המתודה מספקת.

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

Capture & Replay[עריכת קוד מקור | עריכה]

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

בשלב ראשון (שלב ה-Capture) מפעילים את המתודה הנבדקת "מקליטים"/שומרים את תוצאות המתודה ו/או את מצבה של המערכת (state - ערכים במשתנים ובשדות של האובייקטים) לאחר הפעלת המתודה.

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

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

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

בחירת בדיקות יחידה[עריכת קוד מקור | עריכה]

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

  • כיסוי כל הפונקציות של המחלקה
  • כיסוי כל הקלטים האפשריים
  • כיסוי כל המסלולים האפשריים בקוד

תעדוף בדיקות יחידה[עריכת קוד מקור | עריכה]

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

ראו גם[עריכת קוד מקור | עריכה]

קישורים חיצוניים[עריכת קוד מקור | עריכה]