מפירמידה לפגודה: כך תבנו אוטומציית בדיקות נכונה

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

מקור: Unsplash

מאת: עופר פלדמן

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

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

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

דבר ראשון וברור – אפליקציות היום יהיו בדר"כ Client/Server (מול דפדפן או אפליקציות מובייל), והקליינט הוא מוצר בפני עצמו, לפעמים מורכב יותר אפילו מהשרת, עם התנהגות עשירה כך שעם מיעוט בדיקות UI פשוט לא יהיה לנו את הביטחון הדרוש לדעת שהקוד "עובד כמו שצריך". אנחנו אפילו אולי נגלה שרוב הבדיקות אותם נרצה לממש, הם בדיקות UI. וכמו כן, כבר יש כלים ונוחים לבדיקות UI, שלא היו זמינים או אמינים בעבר (כמו Selenium, לבדיקות דפדפנים שונים).

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

דבר אחרון – למי יש זמן לבדיקות ידניות? אני מניח שיכעסו עלי פה כמה אנשי QA… אבל בעולם ששואף להתרחק מה"מפל" ועובר לשחרור גירסה בכל ספרינט (פעמיים בחודש) ואפילו במקומות בעלי CI/CD מתקדם מאוד, לשחרור עבור כל קומיט… אז מתי נספיק להכניס בדיקות ידניות? כמובן שיש לאלו מקום וטעם בתהליך הפיתוח, על מנת לוודא את הפונקציונאליות החדשה, או במסגרת בדיקות של חווית משתמש כללית, בדיקות כלליות על מוצר שלם או אפילו בדיקות "אקספלורציה" (שאינן קשורות לשחרור גרסה), אבל לא כחלק מ"אישור השחרור". התהליך הזה חייב להיות מהיר, ואפילו כמעט מיידי.

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

 

מערכת בדיקות מופרדת Client/Server

נעבור כאן על כל חלק (מלמטה למעלה).

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

בדיקות אינטגרציה ב-Server: למעשה, ניתן לחלק את זה גם לשני חלקים:

  • בדיקות אינטגרציה למערכת קוד שלמה, ללא תלות חיצונית – כאן למעשה נרצה לבדוק את ה API של כל מודול (Microservice, אם יש לכם כאלה). על מנת לפשט את קוד הבדיקה וסביבות ההרצה פה – מומלץ לא לעבוד מול Database ושירותים חיצוניים. לכן נרצה להפריד את סביבת הקוד שיוכל לרוץ באופן "עצמאי" ללא שירותים אלו, כלומר עם Mock services. זה במיוחד משמעותי בקוד העושה שימושים רבים בשירותי ענן (כמו DB מנוהל, או שירותי אחסון קבצים וכו). אם נצטרך להריץ כאלה ולהרים שירותים אלו על כל ריצה, גם זמן ההקמה וגם העלויות עלולות להיות בשמיים. לרוב שירותי הענן יש תחליף, או שניתן לממש לו Mock אחר.
  • בדיקות אינטגרציה "אמיתיות" – כמובן שנרצה גם כאלו, על מנת לראות שהשירות החיצוני עובד כמצופה (בכללי, ועם הקוד שלנו). שכבה זו צריכה להיות נפרדת, כך שנוכל להריצה ע"פ צורך ובחירה, ולא כל פעם.

בדיקות יחידה ב-Client: תחום שלא ממש "תפס" בהרבה מקומות, ומפתחי קליינט מתקשים בד"כ לעשות, אבל יכול מאוד לעזור. בדיקות אלו במיוחד חשובות כשיש לוגיקה מורכבת בקליינט, שאינה ישירות "UI". למשל מיון או פילטור מחוכם, חישובים מורכבים, או כמובן כשיש לוגיקה עסקית בקוד.
כיצד נריץ את הבדיקות האלו (אם צריך להריץ אותם בתוך הקליינט עצמו)? זה תלוי בקליינט כמובן, אבל לרוב הקליינטים יש היום פתרונות רבים בצורת תשתיות שונות. אם לא רוצים "להסתבך" – "טריק" קל הוא לעשות זאת במסגרת בדיקות ה-UI. כלומר, למשל בדפדפן – נכתוב קוד Selenium, המריץ דף מיוחד, שבעת עלייתו רצות הבדיקות ומדווחות את התוצאות לUI, ו-Selenium יבדוק אם יצאה התוצאה המצופה).

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

  • אבל כעת בואו נדבר על נקודה חשובה. אם את הבדיקות קליינט נכתוב מעל השרת שלנו, חזרנו לאותה בעיה ישנה נושנה, ולהריץ הרבה בדיקות כאלה יעלה לנו הון, או זמן רב… לא? הרי כל בדיקה יחידה של לחיצה על כפתור כלשהו תהפוך בעצם לבדיקת אינטגרציה מקיפה, הכוללת את כל השרת, על כל השירותים שלו, וכל השירותים החיצוניים שהוא משתמש בהם… לא? אז זהו, שלא בהכרח.
    אם כתבנו את הקליינט נכון ובכלים מודרניים (ללא שימוש בקוד שרת המייצר UI – כמו ASP או JSP), השרת שלנו מספק בעצם API מוגדר לקליינט. ולכן, כמו בבדיקות האינטגרציה לשרת גם פה נרצה בעצם לעשות Mock ל"שירות" שהוא השרת. מכיוון שלשרת שלנו אין בעצם "תחליף מוכן", אנחנו נכתוב אותו! כלומר, נכין שרת דמה, החושף את אותו API, רק בשליטה מלאה שלנו, בהתאם לטסט המורץ. זאת אמירה קצת "מהפכנית" להרבה אנשים, אבל היא מאוד הגיונית כשחושבים על זה שטסט במילא אמור לכסות אזור מאוד מדויק, ולא להיות תלוי באף טסט אחר. אותה לוגיקה של הפרדה וביצוע Mock שהפעלנו עבור בדיקות יחידה בשרת ובדיקות אינטגרציה בשרת תקפה גם כאן. הפרדה זו תאפשר ריצה מהירה מאוד, ללא צעדי "הכנה" מורכבים. אין צורך להקים משתמש, לקנפג את הדף או להכנס לשלב מורכב בWorkflow. פשוט נכתוב קוד שרת שמחזיר בדיוק את ה"מצב" שאנחנו רוצים עבור הטסט הספציפי. כיצד נעשה זאת? זה מאוד תלוי בסביבת הריצה והאפליקציה הספציפית שלכם, אבל ניתן להעביר משתני סביבה, או יצירת פונקציות אתחול (כמו לוגאין למשל) שתגדיר לשרת הדמה שלנו איזה טסט אנחנו רוצים להריץ כרגע. ככה נוכל לכתוב אפילו אלפי טסטים של UI, ולהריצם בזמן סביר.
  • רק על מנת להשלים את התמונה – נכתוב טסטים מלאים שרצים מהקליינט, ומריצים בדיקת אינטגרציה מלאה (End to End). זאת על מנת לכסות את המערכת כולה, על כל השירותים והמורכבות הפנימית והחיצונית שלה. בדיקות אלו יהיו מעטות מאוד, וישמשו בד"כ כ-Santy למערכת ולא יבדקו התנהגות קליינט ספציפית (ההיקף המדויק יקבע ע"פ המשאבים שיש לכם להריץ כאלו בדיקות).

על פי כל אלה, מתקבלת התמונה הבאה:

זאת התמונה המלאה. אולי שם הולם יהיה "פגודת הבדיקות"?

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

הזכרתי קודם את האפשרות להריץ את הבדיקות בשרתים רבים ובמקביל, בענן וכו'. ככל שיכולות ה-CI/CD של הארגון שלכם גדולות יותר, כך יהיה ניתן לעשות יותר דברים כאלה, באוטומציה חלקית או מלאה. אבל גם בצוות קטנטן, ניתן פשוט להריץ במהירות מערכת בדיקות שנכתבה על פי עקרונות אלו, על מחשב יחיד בסביבת הפיתוח, בהרצה ידנית. כך ש"אין לי עדיין DevOps" הוא למעשה לא תירוץ תקף…

יש לפתח משמעת ארגונית

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

הכותב הוא CTO וממייסדי Stampli

 

כתב אורח

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

הגב

8 תגובות על "מפירמידה לפגודה: כך תבנו אוטומציית בדיקות נכונה"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

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

סידור לפי:   חדש | ישן | הכי מדורגים
אוטומטור
Guest

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

א ב
Guest

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

Papa project
Guest

בתור מקים תשתיות אוטומציה וכותב אוטו אין עדיין משהו שמחליף חווית משתמש

אבי
Guest

חייב לומר:
כתבה מעולה.

הרבה ידע, ולא רק מילים ריקות.

מארק
Guest

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

KEY
Guest

נראה שבאתר גיקטיים 3.0 לקחו את הערות חלק מהקוראים ומיישמים הלכה למעשה תוכן מעשיר ומעמיק.

אך עם כל הכבוד, יש עוד חזיתות לספק תוכן מעשיר. והגיע הזמן להוסיף עוד פודקאסטים מעמיקים ולא רק פודקאסטים על יזמות ושיווק של ג'ון מלקוביץ,
סליחה …, תיקון טעות, מדובר בגיא קטוביץ'! חח.. :)

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

wpDiscuz

תגיות לכתבה: