לקח לי שבוע לפתור באג

לקח לי שבוע לפתור באג
Image by rawpixel.com on Freepik

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

Expected Behavior

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

Steps To Reproduce

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

הפרויקט נבנה באמצעות Webpack ואת הבדיקות E2E אנחנו מבצעים באמצעות Jest ו-Puppeteer. ה-Webpack הוא זה שדואג להגדיר משתני סביבה וככה בעצם הקוד יודע באיזה קובץ config הוא צריך להשתמש, בגלל שה-Jest לא משתמש ב-Webpack היינו צריכים דרך אחרת לטעון config של סביבת בדיקות ולכן באמצעות moduleNameMapper(אחד מהמשתני config של Jest) אמרנו ל-Jest בכל פעם שאתה עושה import לconfig תביא במקום זה את ה-config לסביבת בדיקות. זה האקדח במערכה הראשונה תאכלס.

הדגל החדש עבד ואכן כשהוא היה דלוק האנימציות לא רצו אבל משום מה שכאשר הרצתי את סביבת הבדיקות E2E האנימציות היו רצות בכל זאת, זה היה נראה כאילו לא השתמשנו בקובץ config הנכון. למה??

שעות של Stack Overflow

התחלתי את תהליך הדיבוג בשיטה הקלאסית, הוספתי console.log-ים, הרצתי את ה-Puppeteer לא במצב Headless וראיתי שאכן אני טוען את הסביבת dev, שהיא הסביבת ברירת מחדל, ולא הסביבת test עם ההגדרות שרציתי לאנימציות כפי שהגדרתי לו במיפוי.

אז אמרתי לעצמי ״טוב כניראה ההגדרה של moduleNameMapper ב-jest לא עובדת, כנראה מתנגשת עם איזה הגדרה אחרת שלי״ והתחלתי לחפש בגוגל ״moduleNameMapper is not working״. ואיזה יופי התוצאה הראשונה שקיבלתי היא ״moduleNameMapper` settings in jest.config.js doesn't work on CircleCI״ שהכותרת כוללת בתוכה 90% מהמילים שאני מחפש, זה כנראה אותה בעיה כמו אצלי ולכן אני אקפוץ ישר לפתרון ואנסה אותו.

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

רגע אֵאוּרֵקָה

אחרי הרבה זמן שהלך על שיחות בוואטסאפ עם חברים מתכנתים, ניסויים עם ספריות כאלה ואחרות, על שאלות ב-Stack Overflow ו-Issues ב-GitHub עם כותרות יותר מידי דומות לשאילתא שלי בגוגל התחלתי להתייאש וחיפשתי מישהו לפרוק מולו את תסכולי, בדרך לארוחת צהריים התחלתי לתאר לראש צוות שלי, אמיר, את המצב בצורה הבאה(מה שנקרא לא בדיוק אבל בערך): ״יש לי סביבת jest שמריץ סביבה של puppeteer ומשום מה הסביבה של ה-puppeteer לא מתייחסת להגדרות של ה-jest״. תוך כדי שאני מדבר נדלקת לי נורה בראש ואני מבין מה אני מנסה לעשות בכלל. למה שההגדרות של סביבה אחת ישפיעו על הגדרות של סביבה אחרת?

רצתי לקוד והתחלתי להסתכל איך בעצם כל ה-E2E בפרויקט עובדת(להגנתי יאמר שהייתי בחברה חודשיים בסה״כ ורק סיימתי את תהליך ה-onboarding) וראיתי שבקובץ globalSetup.ts של ה-Jest בעצם לפני הריצה שלו מאתחלים שרתים והשרת של puppeteer, כדי שה-Jest ירוץ עליו, באמצעות הפקודה הפשוטה של npm start, מבלי לציין סביבות.

מה זה אומר בעצם? ההגדרות של ה-Jest עבדו כמו שצריך, פשוט הטסטים הריצו סביבה נוספת בה הם היו עושים פעולות(זה טסטים E2E אז כאילו דהה איך לא חשבתי על זה) ואז מבצעים assert-ים בהתאם לפעולות שבוצעו.

כל מה שהייתי צריך להוסיף זה משתנה סביבה לפקודה של הnpm start וזהו. הטסטים עבדו עם קבצי config הנכונים. הבאג נפתר באמצעות 10 תווים.

סיכום

קורה שלא מבינים מספיק את הדוקומנטציה, לא קוראים בעיון מספיק את השאלות ב-Stack Overflow או ב-GitHub Issues. הרבה באגים נראים בדיעבד כמובנים מאליו אבל זה בסדר לפעמים לעבור דרך ארוכה ומסורבלת בשביל ללמוד בדרך, נכון שזה רק משתנה סביבה אבל כמות ההבנה בכלים שלנו שהבאג הזה נתן יכול  להיות שיחסוך את הזמן הזה בעתיד ובמקרה הזה גם חשף שככל הנראה חסר לנו עוד קובץ קונפיגורציה של Webpack לסביבות טסטים.

אה ופשוט תקנו ברווז גומי כי duck debugging is real. שיתוף חברי הצוות בבעיה היה בסוף המפתח לפיתרון.

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

הבא בתור:

איך LeetCode עזר לי בפיתוח פיצ'ר בעבודה

איך LeetCode עזר לי בפיתוח פיצ'ר בעבודה