רקע
לאורך העשור האחרון (ואולי קצת מעבר לכך) עולם פיתוח התוכנה השתנה באופן עמוק - ממוצר שתוכנן ונבנה במשך חודשים ארוכים, אם לא שנים, עברנו למוצרים שמתעדכנים באופן תדיר - כל כמה שבועות, או אפילו כמה פעמים ביום. העולם העסקי התחרותי בו אנו חיים דורש תגובה מהירה לשינויים בשוק, מענה לצרכים מגוונים של לקוחות ומתן שירות ללקוחות שנעשים סבלניים פחות ופחות. מצד שני, התוכנות שאנחנו בונים היום מורכבות יותר - לא משנה אם מדובר בקלט ממכשירי IOT, שרתים עם אלפי משתמשים, או אפליקציה שמשתמשת בהררי המידע שזמינים היום לכל דורש כדי לשפר את חוויית המשתמש.
בתוך העולם הזה, בו קל ללקוחות להחליף את המוצר שלנו ולעבור למתחרים הצורך הבסיסי של עסקים לספק ללקוחות שלהם מוצר יציב שיענה על הצרכים שלהם רק מתחזק.
מתודולוגיות פיתוח התוכנה המודרניות נותנות מענה די טוב לשאלה "איך אפשר להוציא לשוק תוכנה בזמן כל כך קצר?" אבל המענה הזה לא בא בחינם - כדי לפתח תוכנה מהר האנשים הטכניים צריכים להתמקד בפרטים הקטנים, בשינויים שנעשים עכשיו ולהשאיר את התמונה הגדולה ברובה לצד העסקי. ההתקדמות בצעדים קטנים יכולה להשפיע באופן דרמטי על בדיקת המוצר - השינוי של השבוע הזה יכול להכריח אותנו לחזור על כל העבודה של החודש האחרון, ואם נסתכל יותר מדי מקרוב אנחנו עלולים לשכוח שהשינוי בפינה אחת של המוצר צריך להשתקף גם בעוד שלושה אזורים אחרים, וגם אם לא שכחנו - סט הבדיקות שלנו רק הולך וגדל ונעשה קשה לניהול עם כל יום שחולף, והיכולת לתעדף מבדקים מסוימים כדי לעמוד בלוח הזמנים הולך וקטנה. בקיצור, החיים של מוביל הבדיקות (ובינינו, גם של מנהלי המוצר ושל כל מי שמסתמך על הנתונים שבדיקות יוצרות) נעשים מסובכים יותר.
כדי לענות על הצרכים האלה, חשוב לבחור במתודולוגיית ניהול בדיקות שתתאים לארגון שלנו, לקצב בו אנחנו עובדים, לאנשים שלנו ולסוג המוצר שאנו עובדים איתו. שיטה אחת שעבדה היטב עבורי כמה פעמים וברצוני להציג במאמר הזה היא ניהול עץ מוצר.
עץ בדיקות / עץ מוצר
עץ מוצר הוא כלי לארגון דרישות המוצר עם היסטוריה ארוכה (הרעיון הוצג באופן רשמי לראשונה ב-1967 ע" CK Murtaugh [1]). הרעיון, על רגל אחת, הוא לתאר את התנהגות המוצר שלנו לפי קטגוריות מאורגנות באופן היררכי כדי לאפשר סקירה מהירה של המוצר ומיקוד מהיר באזורים שונים שלו.
למשל, אם ניקח מוצר דמיוני שמוכר תוכן וננסה לצייר את עץ המוצר שלו (ראו איור) אז נוכל לראות שמתוך שורש העץ (שם נמצא שם המוצר) יוצאים כמה ענפים ראשיים - קניות, יוצרי תוכן, אבטחה. בתוך הקניות יש לנו כמה קטגוריות - אישור תשלום (Authorization), גבייה ו-NFT. תחת הגבייה יש לנו חשבוניות ותשלומים וכן הלאה. נשים לב שאפשר היה להמשיך בפירוק ולהגדיר את ההחזרים הכספיים לפי סוג התשלום - אשראי, ביט, פייפאל וכו', אבל המטרה שלנו אינה לפרט את כל דרישות המוצר וליצור עץ ענק שקשה לניווט ולתחזוקה אלא להציג מודל של המוצר שלנו. כזכור, כל המודלים לבסוף יהיו מטריצה של אפשרויות, אך לבסוף אנו מנסים לבנות מודל שיעזור לנו לקבל תמונת מצב מהירה ולכן צריך להחליט מה הנושא ומה הנשוא.
חדי העין בוודאי שמו לב לעובדה קטנה - עד כאן לא הזכרנו אפילו ברמז את הקשר בין עץ המוצר לבין בדיקות, וקל וחומר לגבי כיסוי הבדיקות. כדי להשיג את המטרה הזו נצטרך להוסיף לעץ מידע נוסף - זה יכול להיות אחוז העלים המכוסים, תיאור של "כיסוי מלא\חלקי\לא קיים", או כל דרך אחרת המתאימה לנו. כך, אם נחזור לדוגמה, נוכל לומר שכיסינו את כל מה שרצינו לכסות תחת תשלומים, אבל יש לנו רק כיסוי בסיסי למודול הNFT. במידת הצורך נוכל לראות במסמכים מקושרים (אם עשינו את העבודה כהלכה) את תוכנית הבדיקות ודו"חות ריצה של המודול הרלוונטי ולהבין מה בדיוק חסר.
עץ המוצר הוא כלי מצוין לתקשורת מצד אחד ולקבלת תמונת מצב מהירה מצד שני. רוצים לדעת כמה אנחנו בטוחים בעצמנו לקראת שחרור גרסה? מסתכלים על העץ: מה האזורים שהיו צריכים להשתנות בגרסה? מה מתוך זה נבדק? קל מאוד לזהות פערים בין דרישות, מימוש ובדיקות ובאיזה חלק של המוצר אנחנו צריכים להשקיע יותר מאמץ. כך העץ יכול לשמש אותנו בתהליך קבלת ההחלטות שלנו וגם לעזור כשאנחנו מתקשרים עם בעלי עניין אחרים. למעשה, אחד היתרונות המרכזיים של עץ דרישות הוא שילוב הידע מבעלי תפקידים שונים לתוך מבנה אחד.
אז, איך זה נראה?
עכשיו, אחרי שהבנו מה הוא עץ דרישות, חסרה לנו רק הבנה של פרט קטן אחד נוסף - השקענו, התאמצנו, בנינו עץ דרישות לתפארת, ולפתע - מתחילים לעבוד על הגרסה הבאה (או על סיפור המשתמש הבא). איך לוודא שעץ הדרישות שלנו נשאר עדכני?
במצב אידיאלי, כל הצוותים עובדים עם עץ הדרישות - מנהלי המוצר מגדירים את סיפורי המשתמש ומקשרים אותם לעץ הקיים, צוותי הפיתוח נעזרים בהם כדי להבין מה צריך להתבצע וצוותי הבדיקות - כדי לנהל מעקב אחרי השינויים ולתכנן את הבדיקות הנדרשות. במצב כזה הדברים פשוטים יחסית ועץ הדרישות נשאר שלם בלי מאמץ נוסף, פשוט כי כל העבודה נעשית דרכו. עיקר העבודה במצב הזה יהיה להבין אילו בדיקות נדרשות, מה מתוכן צריך להתווסף לרגרסיה (כלומר, נרצה להריץ שוב באופן תדיר יחסית) ומה יכול להיות חד פעמי (או לרוץ באופן נדיר).
כמובן, לא תמיד העולם יהיה כל כך נוח, ולפעמים נמצא את עצמנו בחברה בה למנהלי המוצר ואנשי הפיתוח יש את הכלים והתהליכים שלהם והם לא מעוניינים לעבוד בעזרת עץ דרישות. במקרה כזה, אנחנו עדיין יכולים להשתמש במבנה הזה ולקבל את רוב היתרונות הגלומים בו אלא שיש לזה מחיר - אנחנו נצטרך להיות אלו שמתרגמים את דרישות המוצר לתוך העץ וישנו סיכון שמתישהו עץ הדרישות שאנחנו מתחזקים יאבד את הסנכרון עם המוצר עצמו. בנוסף, בתהליך כזה נצטרך להתמודד בעצמנו עם דרישות שיכולות להתאים לכמה מקומות בעץ, מה שיקרה יותר מכיוון שהגדרות המוצר לא נכתבות מתוך מחשבה על אותו מבנה.
כמו למשל כשבודקים interoperability במוצרי SAAS, ניתן להראות כיצד החלקים השונים שפיתחו מתאגדים לכדי יכולת עסקית אחת, למרות מורכבת ממספר חלקים שונים, כלומר E2E.
יתרונות וחסרונות השיטה
יתרונות
חסרונות
ניסיון עם השיטה
באחת מעבודותי גויסתי לסדר ולהרים את גוף הבדיקות במוצר enterprise שאמור היה להיות הדבר הבא של החברה. המוצר עבר פיתוח אגרסיבי של שנתיים והקבוצה שכללה אנשי מוצר, כתב טכני, מפתחים ובודקים, עברה גם ניסיון לא טוב של סקראם. הגעתי לחברה עם משימה מוגדרת - להבריא את מצב הבדיקות בחברה ולנהל את אנשי הבדיקות משלל צוותי סקראם.
כחלק מהמהפך הארגוני שבאתי לסייע בו, בזמן החברה אימצה כלי ALM חדש - TFS, מה שאפשר לי לדחוף תהליך עבודה שמתחשב גם בצרכי מחלקת הבדיקות ולהגדיר את התחנות בהן יעברו באגים, סיפורי משתמש וכו'
התהליך שבחרנו בסוף היה כזה: אנשי המוצר והכתב הטכני, עשו עבודת הכנה וסידרו את הדרישות הקיימות למוצר במבנה של עץ בתוך TFS (תוך שימוש ב- Area path), וכך היה בסיס ממנו יכולנו לעבוד. מהנקודה הזו, גרסאות חדשות נכנסו באופן הבא: כל פיצ'ר הוגדר ע"י מנהלי המוצר והכתב הטכני ושולב בעץ הדרישות. עץ הדרישות היה הבסיס לפיו עבדו צוותי הפיתוח וצוותי הבדיקות שהשתמשו בו כדי לעקוב אחרי השינויים שצריכים להיכנס לגרסה וכיסוי הבדיקות שנדרש עבורם. צוותי הפיתוח והבדיקות, בתורם, עדכנו את העץ והוסיפו לו דיווחים על ההתקדמות שלהם, מה שנתן למנהלי המוצר יכולת לראות את קצב התקדמות העבודה.
למעשה, בזכות העובדה שכל הצוותים עבדו מול אותה מערכת ושמירה על קישוריות בין העבודה של צוותים שונים, יכולנו לשמור על מקור אחד שמגדיר את היכולות של המוצר בכל גרסה. לכל דרישה היה קישור למשימות הפיתוח המתאימות ולבדיקות הרלוונטיות, שבתורן היו מקושרות לדו"חות ההרצה[2]. כך, היה קל מאוד למצוא תסריטי בדיקות שצריכים להתעדכן לאחר שדרישות השתנו ולא היינו צריכים להמציא את הגלגל מחדש עם כל שינוי ולכתוב את כל הבדיקות מאפס.
תופעת לוואי מבורכת של עבודה באופן הזה הייתה תקשורת מוגברת בין אנשי המוצר, הפיתוח והבדיקות, מה שבתורו הוביל להיכרות טובה יותר של כל צוות עם עבודת הצוותים האחרים ועם אספקטים שונים של המוצר, ומכאן ליעילות גבוהה יותר של תהליך העבודה. הנראות המוגברת גם עזרה לנו להבין אילו שינויים משפיעים על אילו חלקים במוצר ולהעריך את כמות העבודה שתידרש מרגע ההגדרה ועד רגע שחרור הפיצ'ר.
מבחינתי, זו הייתה חוויה חינוכית מהמדרגה הראשונה. נחשפתי לדרך בה לקוחות חווים את המוצר, איך לחבר בין הצד הטכני לצד העסקה ובעיקר איך מתודולוגיה טובה מייעלת את העבודה ומשפרת את החיים של כל המעורבים.
בארגונים הבאים בהם עבדתי, ניסיתי לשחזר את החוויה המוצלחת הזו ולהטמיע בהם עקרונות דומים. לצערי, לא תמיד הצלחתי לשכנע את כל הגורמים המעורבים שכדאי להם להשקיע את הזמן והמאמץ הראשוניים ולשנות את הדרך בה כל החברה עובדת - לפעמים משיקולים של עלות ראשונית, לפעמים בגלל חוסר היכרות ורתיעה מחידושים ולפעמים הם ניסו את התהליך באופן חלקי בלבד. כדי בכל זאת להרוויח את היתרונות להם הייתי רגיל החלטתי לבנות עץ בדיקות שפועל לפי אותם עקרונות והגעתי לתוצאות טובות במגוון חברות מתחומים שונים. בסך הכל, השיטה עבדה נהדר בכל תחום בו עבדתי - בחברות מולטידיסיפלינריות, מוצרי SAAS, בנקאות, פינטק, RETAIL ועוד.
כמו שאפשר לנחש, במקומות בהם מחלקת הבדיקות ניהלה את העץ לבד היו כמה פערים מעבר לזמן הנוסף שנדרש כדי לבנות את העץ. למשל יכולתי לראות איך סיפורי-משתמש מוגדרים בצורה שמחמיצה קשרים שהיו ברורים לעין כשסידרתי את הדרישות בתוך עץ הבדיקות, מה שהוביל לדרישות חסרות או אפילו סותרות והארגון היה צריך להתמודד עם העלות של שינוי מאוחר יותר של הדרישות. זו כנראה הסיבה לכך שלאחר שלקחתי על עצמי את ניהול העץ וחשפתי את התוצאות לשאר החברה לא לקח הרבה זמן עד שהשפה שיוצר העץ התחילה לשמש את כל החברה ושיפרה את איכות העבודה של כולם - גם במקומות בהם העץ נשאר "של צוות הבדיקות".
מתי נרצה להשתמש בשיטה (ומתי לא)
השיטה מאוד מועילה לכל חברה שמחזיקה מאגר גדול של תסריטי בדיקה שצריך לחזור אליהם מדי פעם - לארגונים צומחים שהחליטו שהגיע הזמן להתמסד ולחברות בינוניות וגדולות. כנראה שהשיטה פחות תתאים לסטארט-אפ בשלבים הראשוניים שלו כאשר המוצר עוד משתנה בצורה דרמטית מרגע לרגע וישנה סבילות גבוהה יחסית לתקלות בשטח.
בכל מקרה, מומלץ לשלב את השיטה הזו יחד עם הכנסת תהליכים ארגוניים ומתודולוגיים אחרים: מעבר לשיטות עבודה אג'יליות, תהליכי ALM , Dev OPS, ניהול פרויקט או סתם לעשות סדר.
בעוד שהשיטה מתאימה לכל מוצר באשר הוא, הרווח המשמעותי יהיה במקומות בהם נדרש מעקב שיטתי אחרי דרישות המוצר על פני גרסאות שונות, וכיסוי בדיקות, ולכן יהיה קל יותר לקדם אותה סביב מוצרים עם רגולציה חזקה כמו מוצרי רפואה, תעופה ולפעמים גם פיננסים. במוצרים בהם המהירות חשובה יותר מאשר איתור תקלות, או בכאלו המורכבים מכמה שירותים פשוטים ובלתי תלויים סביר שניתקל בהתנגדות חזקה (ומבוססת) יותר.
סיכום
אני מקווה שכל מי שקרא את המאמר הזה מצא לפחות דבר אחד שהוא יכול להשתמש בו כדי לשפר את ניהול מאגר הבדיקות או את תהליכי העבודה כדי לחסוך לכולם זמן, כסף וכאב ראש. מגוון המקומות הרחב בו עבדתי ויישמתי בהצלחה את השיטה גורם לי להאמין שיש בה תועלת כמעט בכל סוג של ארגון או מוצר. אמנם, כדי ליישם אותה באופן מוצלח נדרשת מומחיות גבוהה גם בצד העסקי וגם בצד הטכני, אבל בעיני דווקא דרישת הסף הזו יכולה לשפר את היכולות המקצועיות שלנו ולאפשר לנו להתפתח מקצועית. ישנן שיטות נוספות כדי להשיג שיפור בזמני הפיתוח או כדי לשקף החוצה את מוכנות המוצר לשטח, ומה שמצא חן בעיני הוא היכולת לקחת מבני בדיקה מוכרים ופשוטים ולשלב אותם בתוך מבנה שמסתכל על כלל המערכת מקצה לקצה.
[1] https://doi.org/10.4271/670640
[2] אלו מכם שעשו את בחינת CTFL אולי זוכרים את המושג "נעקבות" - אז זה בדיוק זה.