שילוב Cypress.io בתהליך ה-CI

איך מכניסים בדיקות אוטומטיות שיקרו בתהליך ה-Continuous Integration. ומה זה בכלל Continuous Integration?

במאמר הקודם הסברתי על Cypress.io – כלי נהדר לבדיקות E2E. הסברתי גם על הבדיקות האלו. המאמר נגמר בדוגמה של הרצה מקומית. כלומר אני מקליד npx cypress והבדיקות שכתבתי רצות. וזה אחלה להריץ מקומית. אבל חשוב להריץ את זה בהליך CI.

רגע, מה זה CI? זה ראשי תבות של Continuous Integration. מה זה אומר? זה בעצם תהליך ארוך שהקוד החדש שאני כותב עובר ומוודא שהוא מספיק טוב כדי להצטרף לקוד הקיים של המוצר. נהתהליך הזה מורכב בדיקת קוד סטטית, בדיקות אבטחה, בדיקות ביצועים, בדיקות יחידה וכמובן E2E. את זה אנו עושים על מנת לוודא שהקוד החדש תקין. מי שרוצה לשמוע עוד על איך עובדים ב-CI\CD יכול לשמוע את הפרק שלי בפודקאסט מפתחים חסרי תרבות. בגדול – תהליך שרץ כל פעם כשאני עושה PR.

אז הבנו מה זה CI והבנו איך Cypress משתלב איתו. אם בכל פעם שאני עושה פול ריקווסט רצים גם בדיקות unit test וגם E2E אז אנחנו יכולים לדעת אם דברים נשברים. לפני שנדבר על איך משלבים את העניין הזה בתהליך ה-CI, צריך לדבר על המגבלות של E2E. ראשית, גם עם Cypress המהיר יחסית, זה תהליך ארוך אם יש הרבה בדיקות. בנוסף, אם יש הרבה בדיקות E2E חלק מהן יישברו מתישהו בלי קשר לקוד שלי. מכל מיני סיבות. בגלל זה אני נוהג לשלב ב-CI בדיקות פשוטות וספורות שנקראת Sanity. ואותן בלבד. הבדיקות האלו רצות לפני כל pull request לבדוק שהכל לא התפוצץ בגלל הקוד החדש שלי. במקביל, רץ כל ערב הסט השלם של הבדיקות שלפעמים לוקח דקות ארוכות ממש כדי לבדוק ואם הוא נשבר, צריך להבין למה ולתקן. אבל זה לא חוסם PR.

אז יצרנו כמה בדיקות למוצר שלנו, בדיקות Sanity בלבד. אני מריץ אותן מקומית עם npx cypress run. איך אני משלב אותן ב-CI שלי?

ראשית, אני צריך להחליט מול מה אני מריץ אותן. מן הסתם אני לא יכול להרית את Cypress מול פרודקשן. למה? כי אני צריך לבדוק את הקוד החדש, לא את הקוד הקיים. אני צריך להרים שרת בלוקלהוסט, לשים את הקוד החדש עליו ואז להריץ את cypress. אז ראשית – איך אני מרים שרת בלוקאלהוסט? זה תלוי בקוד שלכם. אם למשל יש לכם create react app או מקבילותיה האנגולריות/vueיות אז זה npm run start. אם זה אתר/אליקציה בפלטפורמה אחרת אחר אז זה בדרך כלל פקודה ב-bash שבונה את סביבת העבודה שלכם ומריצה אותו. יכול להיות עם דוקר או בלי. צריך לזכור ש-Cypress כתובת ב-Node.js ועובדת איתו אבל אין שום סיבה שלא להשתמש בה יחד עם קוד שכתוב בשפה אחרת. אנו נכניס את הפקודה שבונה את סביבת העבודה שלנו ל package.json באופן הזה:

וב-npm start אפשר להכניס כל קוד שהוא. למשל:

  "scripts": {
    "start": "python -m SimpleHTTPServer 8000",
  },

או אם יש לכם דוקר:

  "scripts": {
    "start": "docker run myserver",
  },

כמובן אם יש לכם create-react-app זה יראה כך:

  "scripts": {
    "start": "npm run react-scripts start",
  },

מה שחשוב הוא שב-package.json תהיה תחת start (או סקריפט אחר) את הפקודה שמרימה את הסביבה שלכם.

אם אתם מקלידים npm run start הסביבה שלכם צריכה לרוץ תחת localhost. כשהיא רצה, אתם צריכים להיות מסוגלים להריץ את Cypress על הסביבה הזו. זה אומר שבמקום להכנס לכתובת של סביבת הפרודקשן, בקובץ הבדיקה צריכה להיות הכתובת של הסביבה שרצה. למשל:

context('Sanity', () => {
  beforeEach(() => {
    cy.visit('http://localhost:3000');
  });

  describe('First page is loading', () => {
    it('Header is there', () => {
      cy.get('body')
        .find('h1')
        .should('be.visible');
    });
  });

});

אם אני אריץ את Cypress אחרי השינוי הזה, אני אוכל לראות שהוא נכנס ל localhost:3000 ולא ל-url ומריץ את הבדיקות.

השלב הבא הוא לכתוב פקודה שתריץ את שרת הפיתוח, תריץ את הבדיקות. תסגור את שרת הבדיקות ותחזיר סטטוס כמקובל ב-BASH (כלומר 0 בהצלחה, 1 ככשלון).

את זה אנו עושים עם start-server-and-test. מודול נחמד מאוד ב-Node.js. גם הוא, כמו Cypress אגנוסטי לגמרי (כלומר אדיש) למה שהוא מריץ. מה הוא עושה? מריץ פקודה (כל פקודה), בודק אם השרת פעיל. ברגע שהוא פעיל מריץ את Cypress וברגע ש-Cypress מסיימת הורג את השרת. ככה זה נראה:

start-server-and-test start http://localhost:3000 test

הפקודות start ו-test הן הפקודות שמופיעות ב-package.json ויכולות להיות כל פקודה. למשל ככה זה באחד הפרויקטים שלי:

  "scripts": {
    "start": "react-scripts start",
    "cypress": "cypress open",
    "cypress:ci": "cypress run",
    "e2e": "start-server-and-test start http://localhost:3000 cypress:ci"
  },

ה-start יכול להיות כל דבר, ה-test יכול להיות כל דבר. פה אפשר לראות שאני מריץ את שרת הבדיקות הלוקלי בפורט 3000. אבל כל פרויקט עובד לפי איך שבא לו.

ברגע שאני מריץ את הפקודה npm run e2e מקומית אני רואה איך סביבת הפיתוח קמה, ה-Cypress רץ, מריץ את הבדיקות. מ סיים. שרת הפיתוח נסגר ואז הכל מחזיר את הסטטוס (מצליח או לא מצליח).

וזה? זה מה שמספיק לתהליך CI. וכשאני מריץ את הכל אני מקבל 0 (הצלחה) או 1 (כשלון). עכשיו נותר לקשור את זה ל-CI שלכם תלוי במערכת אבל מפה זה קל. במאמר הבא אני אראה איך קושרים את זה לגיטהאב actions ואיך מדבגים. שגם זה חשוב.

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

פוסטים נוספים שכדאי לקרוא

תמונת תצוגה של מנעול על מחשב
פתרונות ומאמרים על פיתוח אינטרנט

הגנה מפני XSS עם Trusted Types

תכונה ב-CSP שמאפשרת מניעה כמעט הרמטית להתקפות XSS שכל מפתח ווב צריך להכיר וכדאי שיכיר.

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

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

ESP32 מאפס לילדים

מדריך ל-ESP32 לילדים ולהורים מאפס

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

גלילה לראש העמוד