תעדוף בדיקות AI: היכן נשבר צינור הבנייה
מערך הבדיקות המלא לכל שינוי מפסיק להיכנס לחלון העבודה. הרגרסיה, שבעבר הסתיימה עד סוף המשמרת, נמשכת כעת עד הבוקר: את התוצאה פוגשים כבר במשימה אחרת, עם הקשר שאבד ותמונה חצי-בנויה של השינויים.
צוואר הבקבוק של צינור הבנייה אינו הבנייה ואינו הפריסה לסביבת הבדיקות, אלא ההמתנה לרגרסיה.
הבנייה מסתיימת בתוך דקות, ואילו התור להרצה נמתח לשעות, וזמן המשוב של המפתח כמעט אינו תלוי בגודל השינוי: תיקון של שורה אחת במודול משותף גורר אחריו את כל המערך, אף שבפועל קשורים אליו בדרך כלל אחוזים בודדים של בדיקות.
אי אפשר לקצץ את המערך ישירות. קל להסיר בדיקות מיותרות, אך המחיר של רגרסיה שהוחמצה הוא חזרה לאחור, חקירת תקלה ואובדן אמון בצינור עצמו, ולכן צוותים משאירים הכול וסובלים את העיכוב.
המשימה שונה: להריץ לא את כל המערך, אלא את הבדיקות שבאמת קשורות לשינוי. תעדוף בדיקות AI נשען על היסטוריית כשלים, מפת התלויות של המודולים, הקבצים שהשתנו וסטטיסטיקת בדיקות לא יציבות — ומציב בראש התור את מה שסביר מאוד שיתפוס את הפגם.
נפרק כיצד זה נסגר בפועל: אילו נתונים נדרשים למודל, כיצד לוודא שהוא אינו מחמיץ פגמים, וכיצד להטמיע את בחירת הבדיקות בצינור בלי לאבד שליטה על השחרור.
מה נותן ריצה סלקטיבית של בדיקות בכל קומיט
בכל קומיט מורץ לא כל מערך הבדיקות, אלא תת-הקבוצה שהקומיט הזה באמת נוגע בה. המערכת משווה בין הקבצים שהשתנו לבין מפת התלויות של המודולים ולהיסטוריית הכשלים: בדיקות שכבר תפסו פגמים בקוד הזה עולות לראש התור, ואילו אלו שברור שאינן קשורות עוברות לריצה המלאה בלילה. ריצה סלקטיבית אינה «לקצץ בבדיקות», אלא לסדר אותן מחדש כך שהאות יגיע מוקדם יותר.
ההשפעה המדידה הראשונה — זמן ריצת הבדיקות. המשוב על הענף מגיע בתוך דקות בודדות במקום עשרות, והמפתח אינו עובר למשימה אחרת בהמתנה לתוצאה. זה משנה הרגל: השינויים נעשים קטנים יותר, וקונפליקטים במיזוג זולים יותר לפתרון.
השנייה — כיסוי הרגרסיה. שיעור הפגמים שנתפסים נשמר ברמה של המערך המלא: אף בדיקה אינה נמחקת, משתנים רק הסדר ומועד ההרצה. הריצה הלילית עדיין מתבצעת במלואה ומשמשת נקודת בקרה, ולא סיכוי יחיד להבחין במשהו.
השלישית — העומס על תשתית הבנייה. ענפים מקבילים מפסיקים להתחרות על אותם מכשירים, התורים להרצה מתפוגגים, והבנייה אינה הופכת עוד לצוואר בקבוק לפני השחרור. מכאן גם היציבות של השחרור: ענף השחרור מקבל מערך בדיקות צפוי במקום הגרלה בגלל מכונות עמוסות וזמני המתנה.
מצבי הרצה: השוואה בין גישות והמגבלות שלהן
מצב הרצת הבדיקות קובע כמה זמן ממתינים לתוצאה אחרי השינוי ואיזה חלק מהרגרסיה הוא מכסה. הבחירה תלויה לא בגודל הפרויקט, אלא במידת הפירוט של גרף התלויות בין המודולים ובשאלה אם קיימת היסטוריית הרצות מצטברת.
בפועל משווים ארבע סכמות — מריצה מלאה ועד להיברידית. אף אחת מהן אינה מנצחת תמיד: המגבלות של הגישה מתגלות בדיוק במקום שבו נגמרים הנתונים שעליהם היא בנויה.
| מצב הרצת בדיקות | מתי מתאים | מגבלות הגישה |
|---|---|---|
| ריצה מלאה | גרף תלויות לא יציב או חלקי, בדיקות שחרור, מערך בדיקות קטן | הזמן גדל ליניארית: התוצאה מגיעה כעבור עשרות דקות, שינויים מקבילים ממתינים בתור |
| סינון לפי תלויות | מאגר קוד אחיד עם גרף מודולים מפורש, שינויים ממוקדים | מאבד קשרים שאינם בגרף: הגדרות, סכמות נתונים, מתגי תצורה |
| מודל סטטיסטי לסינון | אינטגרציה תכופה, היסטוריית הרצות וכשלים מצטברת | בקוד חדש ואחרי עיבודים מחדש גדולים הדיוק יורד, נדרש פיקוח על שיעור הפגמים שהוחמצו |
| מצב היברידי | מחזור שחרור בקצב שינויים גבוה | מורכב יותר להגדרה: שני מערכי כללים, נדרשת השוואה תקופתית לריצה מלאה |
הסכמה הבסיסית שאנחנו מיישמים היא היברידית: ענפי עבודה מקבלים משוב מהיר, וריצות שחרור ולילה מתבצעות במערך מלא. הפער בין המערך הנבחר למערך המלא נהיה גלוי לפני הפריסה, ולא אחריה. את המעבר בין המצבים אנחנו משאירים בשליטה, כך שבכשל בסינון המערכת תחזור לריצה מלאה, ולא לדוח ריק.
כיצד מתבצעת ההטמעה: שלבי העבודה ההנדסית
ההטמעה מתבצעת בשלבים, וכל שלב מסתיים בארטיפקט שאפשר לבדוק: רשימת בדיקות, מפת קשרים, דוח מצב צל. בלי זה מודל הסינון נשאר קופסה שחורה, והצוות לא ימסור לו את הזכות להחליט אילו בדיקות אפשר להחמיץ.
- ביקורת מערך הבדיקות. עורכים מלאי של הבדיקות הקיימות: משך, תדירות כשלים שגויים, כפילויות ובדיקות שמעולם לא נכשלו בכל ההיסטוריה. הפלט — רשימה שממנה רואים מה בכלל יש טעם לסנן.
- איסוף סטטיסטיקת הרצות. שולפים את ההיסטוריה ממערכת הבנייה הרציפה: אילו בדיקות הורצו, אילו נכשלו, איזה קוד השתנה באותו מערך שינויים. זוהי מדגם האימון — בלעדיו אין במה לאמן את המודל.
- מפת תלויות. בונים קשר «מודול שהשתנה → הבדיקות שמכסות אותו». קשרים מפורשים נלקחים מניתוח התלויות בקוד, וקשרים מרומזים — מהכשלים בפועל בהיסטוריה: חלק מהפגמים צפים בבדיקות שאינן קשורות פורמלית לשינוי.
- אימון מודל הסינון. המודל מדרג את הבדיקות לפי הסתברות כשל משינוי מסוים. את הסף מכיילים כך שתרחישים קריטיים לעסק יורצו תמיד, ללא תלות בציון.
- מצב צל. המודל פועל במקביל לריצה מלאה ורק מציע סדר, בלי לכבות דבר. משווים את הסינון שלו לבדיקות שנכשלו בפועל ומחשבים איזה שיעור פגמים הוא היה מחמיץ.
- הטמעה בצינור. מתחילים בענפים בודדים, ואחר כך מעבירים את הזרימה העיקרית. המערך המלא נשאר זמין ידנית, ושינויים באזורים קריטיים מפעילים לפי כלל את הכול.
- מסירה לתחזוקה. מוסרים תיעוד, נהל אימון מחדש ומדדים עם התראות: אם שיעור הכשלים שהוחמצו עולה, הסינון חוזר אוטומטית למערך מלא.
לאחר המסירה הצוות מעדכן את המודל בעצמו עם שינויי הקוד — אין צורך במעורבות חיצונית לשם כך.
מה נשאר במאגר הקוד לאחר מסירת העבודה
אנחנו מוסרים לא רק שירות תעדוף עובד, אלא גם את כל מה שהצוות צריך כדי לשנות את כללי סינון הבדיקות בלעדינו. כל ארטיפקט נמצא במאגר הקוד לצד הקוד, מנוהל בגרסאות ועובר סקירה — כעבור חצי שנה איש לא מנחש למה בדיקה מסוימת נכנסה לריצה או נשארה מחוצה לה.
- תצורת הסינון — קובץ עם כללים: אילו שינויים מפעילים ריצה מלאה, ואילו בדיקות נחשבות קשורות למודול. השינויים עוברים סקירה רגילה, ואין צורך לערוך את קוד המודל לשם כך.
- מפת תלויות — גרף הקשרים בין מודולים, בדיקות וחוזים חיצוניים, שנאסף מניתוח סטטי ומהיסטוריית הרצות. נשמרת בפורמט קריא למכונה ומתעדכנת לפי לוח זמנים.
- כללי חריגים — רשימת בדיקות שנכנסות תמיד לריצה: תשלומים, אימות, תרחישים קריטיים. עבור כל אחת מהן מתועד למה היא הוצאה מתחת למודל.
- דוחות על איכות החיזוי — שיעור הפגמים שהוחמצו, שיעור הבדיקות שנבחרו, זמן הריצה לפני ואחרי. נוצרים אוטומטית לפי לוח זמנים.
- הוראות למהנדסים — כיצד להוסיף בדיקה, כיצד לסמן תלות חדשה, מה לעשות אם המודל טעה והחמיץ רגרסיה.
- נהל תחזוקה — מי, באיזו תדירות ולפי אילו מדדים בוחן מחדש את הספים והכללים; מה לעשות כאשר הדיוק יורד.
- תיעוד הפתרון — תרשים הרכיבים, נקודות החיבור עם צינור הבנייה, פורמטי הנתונים ויומן ההחלטות שהתקבלו עם הנימוקים.
מקרה בוחן: כיצד סינון AI קיצר את ריצת הרגרסיה
לפני ההטמעה מערך הרגרסיה של 4,200 בדיקות אוטומטיות נמשך כתשע שעות, והריצה הלילית לא הספיקה להסתיים לפני הבדיקה של הבוקר. הצוות החזיק מערך מלא רק לפני שחרור, ובשאר הימים הריץ רשימה מצומצמת «לפי העין» — חלק מהבדיקות כובו ידנית, ופגמים בנתיבים נדירים הגיעו עד סביבת הבדיקות.
אימנו מודל על היסטוריית ההרצות: השווינו בין הקבצים שהשתנו לבדיקות שנכשלו בבניות קודמות, הוספנו את מפת התלויות בין המודולים ומשקל לפי קריטיות. הגישה של Test Impact Analysis נותנת לכל בדיקה הערכה של הסתברות לתפוס רגרסיה — ועל בסיסה המערכת מרכיבה מדגם עבור מערך שינויים מסוים.
מדדים לפני ואחרי: משך הרגרסיה הצטמצם מ-9 שעות ל-55 דקות, היקף הריצה הלילית — מ-4,200 ל-700–900 בדיקות, ושיעור הפגמים שנתפסו נשאר ברמה של המערך המלא.
החמצות שגויות ברבעון הראשון — 0.3%: שלושה מקרים שבהם הפגם נמצא רק בריצה מלאה. ניתחנו את הסיבות: שניים היו קשורים לשינויים בתצורה מחוץ לקבצים הנמצאים במעקב. הוספנו כלל — מודולים בסיכון גבוה וכל מה שקשור לסכמת הנתונים נכנסים תמיד למדגם במלואם.
את הריצה המלאה לא הסרנו: היא נשארה לפני השחרור ופעם ביממה כגיבוי, אך הפסיקה להיות צוואר בקבוק. חלון הלילה נכנס בתוך 40 דקות, הבדיקה של הבוקר מתחילה מסטטוס עדכני, ומחזור השחרור הצטמצם משבוע לשני-שלושה ימים.
במה נבדל המודל מחלוקה ידנית של בדיקות?
חלוקה ידנית של בדיקות היא מערכים קבועים לפי רמות: מינימום עשן לבנייה, בדיקות אינטגרציה — פעם ביממה, רגרסיה מלאה — לפני שחרור. רמות הבדיקות קשורות לאירוע ולא לתוכן השינוי: אותה רשימה רצה גם אחרי שינוי בתבנית וגם אחרי שכבת גישה לנתונים שנכתבה מחדש.
למערכים סטטיים יש חוזקות משעממות אבל אמיתיות: זמן ריצה צפוי, ביקורת מובנת — רואים מה נבדק בכל שחרור. נקודת התורפה זהה: המערך לא יודע מה השתנה, ולכן או שהוא גדל עד שעות, או שחותכים אותו ידנית — וחלק מהנתיבים נשארים בלי בדיקה עד התקלה.
סינון דינמי יוצא מהשינוי: מפת התלויות מקשרת בין הקבצים שהשתנו, המודולים וסכמות הנתונים לבין בדיקות מסוימות, והיסטוריית הכשלים קובעת את סדר ההרצה — ראשונות רצות אלו שתפסו רגרסיה בתדירות גבוהה יותר באזור שנפגע. זה בדיוק תעדוף בדיקות AI: המודל מעריך את הסתברות הכשל ואת מחיר הבדיקה, ולא בוחר לפי מסכת נתיב.
הגבולות של הדינמיקה הוגנים: תלויות מרומזות — הרכבת תצורה, יצירת קוד, מיגרציות — לא תמיד נכנסות למפה, ובדיקה שנפגעה עלולה שלא להיבחר. לכן הסינון נשען על מפה שמתעדכנת יחד עם הבנייה, ועל ריצה מלאה לפני השחרור כגיבוי מפני החמצות מצטברות.
אין טעם להשוות בין הגישות כ«או-או»: סינון דינמי חוסך זמן בכל בנייה, ורמות סטטיות מחזיקות את הגבול לפני השחרור. חלוקה ידנית נשארת נחוצה במקום שבו התלויות אינן נראות: שירות חדש, רכיב חיצוני, תרחיש נדיר.
ספקות טכניים: החמצות שגויות ואיכות החיזוי
כל מערכת שמחליטה אילו בדיקות להריץ ואילו לא ראויה לספקנות: מחיר הטעות כאן הוא פגם בשחרור. לכן את איכות החיזוי אנחנו מודדים לא בדיוק ממוצע, אלא בשיעור ההחמצות השגויות — מקרים שבהם המודל ראה בדיקה כלא רלוונטית והיא הייתה נכשלת. להלן חמש הסתייגויות שנשמעות לרוב במפגשים טכניים, ומה שסוגר כל אחת מהן בארכיטקטורה.
מה אם המודל יטעה ויחמיץ פגם?
ההחמצות השגויות מוגבלות בריצה מלאה כגיבוי: בענפי שחרור ולפי לוח הזמנים הלילי מערך הבדיקות מבוצע במלואו, ללא תלות בחיזוי. בתוך המשמרת ההחלטה מתקבלת לפי סף ביטחון — ברגע שהוא יורד, התעדוף נכבה והכול רץ. כל החמצה שגויה מתועדת עוברת לניתוח והופכת לדוגמת אימון, ולא נשארת ביומנים.
כיצד המערכת מתנהגת באתחול קר של המודל?
כל עוד אין סטטיסטיקה של היסטוריית כשלים וקשרים בין שינויים למודולים, התעדוף אינו נדלק כלל: רצה ריצה מלאה, והמערכת צוברת תצפיות. המודל נכנס למצב עבודה בהדרגה, ככל שנאספים נתונים, ולא לפי תאריך בלוח. עד אז התנהגות הצינור אינה שונה מהרגיל — אין סיכון של שבוע «עיוור».
האם יהיה צורך לשכתב בדיקות קיימות?
לא. התעדוף נבנה מעל המערך הקיים: לוקחים מטא-נתונים ממערכת הבנייה וממאגר הקוד, ומשווים בין השינויים לאזורי הכיסוי — את מתודולוגיית Test Impact Analysis מיישמים על מה שכבר קיים. די בשמות בדיקות יציבים ובסימון מודולים; אין צורך להעביר את הלוגיקה לפריימוורק אחר.
מי מתחזק את המודל לאחר המסירה?
איכות החיזוי נשארת גודל מדיד: שיעור ההחמצות השגויות ודיוק הסינון נמצאים במעקב בלוח בקרה, והאימון מחדש מתבצע לפי לוח זמנים ולפי טריגר של ירידה בביצועים. אנחנו מוסרים נהל אימון מחדש, מערך חתכי בקרה לבדיקת רגרסיה של המודל ותיעוד — והצוות ממשיך לעבוד בלעדינו.
נדון במשימה שלכם: מה לשלוח להערכה
כדי שהערכת ההטמעה תישען על עובדות ולא על שאלון, די לנו בנתוני המקור של הפרויקט — כיצד בנויה כעת ריצת הבדיקות והיכן היא מאבדת זמן. להלן המערך המינימלי; אם משהו חסר, נדון במשימה ונעזור להבין כיצד לאסוף אותו.
- מפת מערכי הבדיקות: כמה בדיקות יש, לאילו מודולים הן קשורות, אילו בדיקות נחשבות קריטיות.
- היסטוריית הרצות של מספר שבועות: זמן הריצה המלאה, שיעור הכשלים בלי פגם אמיתי.
- תיאור הצינור: באיזה שלב רצות הבדיקות, מה כבר מקביל, והאם קיים מטמון תוצאות.
- הקשר בין קוד לבדיקות: האם קיים סימון בדיקות לפי קבצים ומודולים, וכמה הוא מלא.
- זרימת השינויים: באיזו תדירות ובאילו היקפים מגיעים השינויים, ומי מאשר את מוכנות השחרור.
- מגבלות: הרשאות גישה, מדיניות אחסון היסטוריית ההרצות, דרישות לבידוד נתונים.
- קו מתאר להרצת פיילוט: צוות אחד, שירות אחד, שיעור ההרצות שבמעקב.
לפי הנתונים האלה נחזור עם הערכת הטמעה ותוכנית עבודה לפי שלבים — מניתוח היסטוריית ההרצות ועד הרצת פיילוט בקו מתאר מוגבל. מראש נקבע את המדדים שלפיהם נחשב את האפקט: זמן הריצה לשחרור, שיעור הפגמים שהוחמצו, שיעור ההרצות מחדש הידניות.







