פיתוח אפליקציות6 דקות קריאה

קייס סטאדי: CI/CD ובדיקות יחידה לשלוש אפליקציות בנקאות white-label בעשרה שבועות

איך Mobian Studio העבירה SDK של פינטק ושלוש אפליקציות בנקאות white-label מ-builds ידניים למערכת CI/CD אחת, וכמעט שילשה את בדיקות היחידה של ה-SDK.

רוב המאמרים על CI/CD מתארים איך פייפליין אמור להיראות. המאמר הזה מתאר פייפליין שבאמת בנינו: עבור פלטפורמת פינטק שה-Android SDK שלה מפעיל שלוש אפליקציות בנקאות white-label.

כשהתחלנו, לאף אחד משישת הריפוזיטוריז לא היה CI עובד. ה-builds נעשו ידנית, מספרי הגרסה הועלו ידנית ב-commits, וספרייה אחת הייתה קיימת רק על המחשב של מפתח אחד. עשרה שבועות אחר כך, ה-SDK ושלוש אפליקציות הלקוח חלקו מערכת CI/CD אחת, כל build לבודקים היה ניתן לשחזור מתגית Git, וחבילת בדיקות היחידה של ה-SDK כמעט שולשה.

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


נקודת המוצא

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

  • Android SDK של כ-29 מודולי Gradle, שהופך JSON מצד השרת למסכים נייטיב, ומטפל גם בתשלומים, בביומטריה ובסריקת כרטיסים.

  • שלוש אפליקציות בנקאות white-label שבנויות על ה-SDK הזה, ולכל אחת מודל ענפים ושחרורים משלה.

  • ספריית networking וחבילת בדיקות end-to-end שבבעלות צוות ה-QA.

ביולי–אוגוסט 2026 המצב נראה כך:

  • תבניות CI ישנות ישבו בריפוזיטורי של ה-SDK, אבל שום דבר לא רץ.

  • ה-version codes הועלו ידנית: כ-95 commits כאלה באפליקציה אחת מאז 2025, ו-28 באפליקציה אחרת.

  • אי אפשר היה לשחזר build מ-checkout נקי, כי ספרייה אחת הייתה קיימת רק ב-Maven cache המקומי של מפתח.

  • חלק ממודולי הבדיקות של ה-SDK אפילו לא התקמפלו, וריצת ה-CI הראשונה חשפה את זה.

  • ל-SDK היו 1,122 בדיקות שרצו ו-8.1% כיסוי כולל; לאפליקציה הראשית היו 56 בדיקות.

📌 תובנה מרכזית:

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


האילוצים

הפייפליין היה צריך להתאים לתשתית האמיתית של הלקוח, לא לתשתית אידיאלית:

  • GitLab באחסון עצמי, שהועבר מ-gitlab.com ביולי 2026.

  • runner משותף אחד של macOS בלי Docker, שמשמש גם פרויקטים אחרים בחברה, עם workspace שנשמר בין jobs.

  • builds שמשתרעים על שני ריפוזיטוריז: כל build של אפליקציה משלב ענף של האפליקציה עם ענף של ה-SDK שאולי עדיין לא מוזג.

  • תחום בנקאי מפוקח, שדוחף לכיוון builds שאפשר לשחזר, חתימת ריליס שנשארת מחוץ ל-Git וסריקת תלויות.


מה בנינו: פייפליין אחד לשלוש אפליקציות

1. טופס ווב אחד עד לבודקים

build לבודקים מתחיל מטופס אחד ב-GitLab: בוחרים את ענף האפליקציה, את ענף ה-SDK, את סוג ה-build ואת קבוצות הבודקים. אז הפייפליין מריץ שישה שלבים:

  1. Prepare: ממפה את ענף ה-SDK ל-commit יחיד, כך שכל job בהמשך משתמש בדיוק באותו קוד SDK.

  2. Test: בדיקות יחידה של האפליקציה וגם של ה-SDK, כיסוי וסריקת תלויות.

  3. Build: APK חתום (ובנוסף AAB ל-Play Store בשחרורים), עם פרטי גישה לחתימה שנלקחים ממשתני CI.

  4. Distribute: הפצה ב-Firebase App Distribution לקבוצות הבודקים שנבחרו.

  5. Notify: תגובה ב-Jira בכל טיקט שנכלל, עם הקישור ל-build והכיסוי, והעברה לסטטוס “Ready for QA”.

  6. Tag: אותה תגית על ה-commit של האפליקציה וגם על ה-commit של ה-SDK.

2. כל build לבודקים ניתן לשחזור

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

3. תבנית אחת, העברות מכניות

שלוש האפליקציות מריצות את אותו פייפליין בן שישה שלבים. רק כמה קבועים שונים ביניהן (תווית Jira, קידומת התגית, קבוצות הבודקים), והם נמצאים ב-job תבנית מוסתר אחד. האפליקציה השנייה והשלישית הועברו בתוך ימים, אף שאחת מהן משתמשת במודל של release branches והיו בה שבעה חסמים נפרדים שהיה צריך לפתור.

4. שערי איכות במקום שבו אנשים כבר עובדים

  • תוצאות הבדיקות בלשונית Tests של ה-merge request.

  • תג כיסוי לוגיקה ב-widget של ה-merge request, וסימוני כיסוי על השורות שהשתנו.

  • SonarQube על הענף הראשי.

  • OWASP Dependency-Check עם CycloneDX SBOM באפליקציה הראשית.

5. runner משותף שמתייחסים אליו כלא מהימן

הסודות נמצאים רק במשתני CI, שום דבר לא נשמר על ה-runner, כל job משכפל את ה-SDK ל-workspace משלו (אחרי שבעבר jobs מקביליים מחקו זה לזה את ה-checkout), ו-builds חתומים של ריליס תמיד עוקפים את ה-build cache.


מה בנינו: אסטרטגיית בדיקות שמתחילה בארכיטקטורה

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

1. למדוד את הקוד שחשוב

הגדרנו סט לוגיקה: domain, data, כלי עזר שאינם תלויים ב-Android, מנועי הבקשות והאירועים, ו-ViewModels בסיסיים. קוד UI, חיווט DI וקוד שנוצר אוטומטית עדיין מדווחים, אבל אין להם יעד. זה לבדו שינה את נקודת המוצא הכנה מ-8% (כל בסיס הקוד) לכ-24% (לוגיקה).

2. ארכיטקטורה עם מנגנון ראצ’ט

שבעה כללי ארכיטקטורה אוטומטיים רצים כבדיקות יחידה, למשל: אין טיפוסי Android בקוד לוגיקה ואין dependency injection גלובלי. ההפרות של היום מוקפאות בקובץ baseline: הפרה חדשה מכשילה את ה-build, וכך גם הפרה שתוקנה, עד שמסירים אותה מה-baseline. החוב יכול רק לקטון.

3. קודם seams, אחר כך בדיקות

כל תלות ב-Android או בספק חיצוני (אנליטיקס, הרשאות, ביומטריה, cache של מסכים, חתימת בקשות) קיבלה ממשק קטן בשכבת ה-domain ו-adapter מחוץ לשער הכיסוי. אחרי זה, הלוגיקה רצה על JVM רגיל בתוך מילישניות, וכתיבת בדיקות נעשית זולה.

4. לקבע התנהגות, לא לתקן אותה בשקט

בדיקות שכבת ה-data מתעדות מה הקוד עושה היום. כל התנהגות מפוקפקת הופכת לשאלה לצוות המוצר או לצוות צד השרת במקום לשינוי שקט: 76 שאלות פתוחות עד עכשיו. כשמתקבלת החלטה, בדיקת הקיבוע נכשלת בכוונה ומתעדכנת יחד עם התיקון.


התוצאות

כל הנתונים שלהלן נכונים ל-5 באוקטובר 2026, ונלקחו מה-API של הפייפליינים ב-GitLab או נספרו מהריפוזיטוריז.

מדד לפני אחרי
ריפוזיטוריז עם CI עובד 0 מתוך 6 4 מתוך 6 (SDK + 3 אפליקציות)
ממיזוג ועד לבודקים builds ידניים, העלאת גרסה ידנית כ-6–8 דקות, אוטומטי לחלוטין
builds לבודקים דרך הפייפליין — 101 מאז 8 בספטמבר
ריצות פייפליין — כ-530
בדיקות יחידה ב-SDK 1,141 (11 בספטמבר) 3,246 (×2.8)
כיסוי לוגיקה ב-SDK כ-24% 70.9%
בדיקות שנכשלות חוסמות מיזוג לא כן, ב-SDK ובאפליקציה הראשית
ייבואי Android בקוד לוגיקה 298 192 (−36%)
שחזור build לבודקים לא אפשרי checkout של תגית אחת בשני הריפוזיטוריז

התקופה המהירה ביותר: כיסוי הלוגיקה עלה מ-30.7% ל-70.9% בשבעה ימים (28 בספטמבר עד 5 באוקטובר), כשכל שכבת ה-data כוסתה במסגרת 13 טיקטים. הקפיצה הזו התאפשרה רק כי ה-seams הארכיטקטוניים כבר היו במקום.

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

מה עדיין פתוח

אנחנו מעדיפים לפרסם את הפערים לצד התוצאות:

  • עדיין אין רצפת כיסוי: מיזוגים נחסמים על בדיקות שנכשלות, לא על ירידה בכיסוי. אבני הדרך של 40% ו-60% כבר מאחורינו; 80% עדיין לפנינו.

  • בשתי אפליקציות הבדיקות עדיין לא חוסמות, והן עוד לא אימצו את ערכת הבדיקות המשותפת.

  • לשני ריפוזיטוריז אין CI, ובדיקות ה-end-to-end עדיין רצות על מכונה מקומית.

  • runner יחיד הוא נקודת כשל יחידה: ביומיים, jobs חיכו עד שעבר הזמן המוקצב להם (timeout) בזמן שהוא לא היה זמין. runner שני או מאגר עם autoscaling הם הצעד הבא.


ה-playbook שבו אנחנו משתמשים עכשיו גם עם לקוחות אחרים

  1. לנעול תלויות משותפות ולתייג כל ריפוזיטורי שמשתתף ב-build, כך שאפשר לשחזר כל build לבודקים.

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

  3. לסגור את המעגל במקום שבו אנשים כבר עובדים: הקישור ל-build והכיסוי מגיעים לטיקט ב-Jira ול-merge request.

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

  5. ראצ'ט, לא big bang: להקפיא את ההפרות של היום ולהכשיל כל הפרה חדשה.

  6. להתייחס ל-runner משותף כלא מהימן: סודות במשתני CI, ו-builds של ריליס אף פעם לא נשמרים ב-cache.

סיכום

בתוך עשרה שבועות, משפחת מוצרי פינטק עברה מ-APKs שנבנו ידנית למערכת CI/CD אחת: כ-530 פייפליינים, 101 builds אוטומטיים לבודקים, דרך ממיזוג ועד לבודקים בתוך דקות, וחבילת בדיקות SDK שגדלה מ-1,141 ל-3,246 בדיקות עם כיסוי לוגיקה של 70.9%. שום דבר מזה לא דרש ספק CI חדש, רק פייפליין שתוכנן סביב התשתית האמיתית של הלקוח וארכיטקטורה שמאפשרת בדיקות.

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

שאלות נפוצות

כמה זמן לקחה הקמת ה-CI/CD?

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

למה למדוד כיסוי של לוגיקה ולא כיסוי כולל?

כיסוי כולל סופר גם קוד UI, חיווט של dependency injection וקוד שנוצר אוטומטית, שבהם לבדיקות יחידה יש ערך מועט. כיסוי לוגיקה סופר רק את קוד ה-domain, ה-data וה-engines, שבו באגים עולים כסף. זה הופך את המספר לכן ואת היעד לבר השגה. בפרויקט הזה נקודת המוצא הייתה 8.1% כיסוי כולל, אבל כ-24% כיסוי לוגיקה, עוד לפני שנכתבה בדיקה חדשה אחת.

האם הפייפליין רץ על CI בענן?

לא. הלקוח מפעיל GitLab באחסון עצמי עם runner משותף יחיד של macOS, ולכן הפייפליין תוכנן בהתאם: כל job מקבל checkout משלו של ה-SDK, הסודות נמצאים רק במשתני CI, ו-builds חתומים של ריליס אף פעם לא נלקחים מה-build cache המשותף.

האם העבודה הסתיימה?

לא לגמרי, ואנחנו מעדיפים לומר את זה. רצפת הכיסוי (חסימת מיזוג כשהכיסוי יורד) עוד לא נבנתה, הבדיקות בשתיים מהאפליקציות עדיין לא חוסמות, וה-runner היחיד נשאר סיכון מבחינת קיבולת וזמינות. אבן הדרך של 80% כיסוי לוגיקה עדיין לפנינו.

האם הגישה הזו יכולה לעבוד במוצר iOS או קרוס-פלטפורם?

העקרונות עוברים: לנעול תלויות משותפות, לתייג כל build לבודקים, למדוד את הקוד שחשוב ולהוסיף בדיקות אחרי שהארכיטקטורה מאפשרת אותן. הפרויקט הספציפי הזה היה Android בלבד, ולכן ב-iOS הכלים שונים (Xcode, Swift Package Manager, XCTest), אבל ה-playbook נשאר אותו דבר.

הערכה ללא עלות · ללא התחייבות

מתכננים פיתוח על ה-stack הזה?

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

  • 1אנחנו עוברים על המוצר, ה-stack ומפת הדרכים שלכם
  • 2אנחנו מצביעים על הסיכונים שראינו בפרויקטים דומים
  • 3תוך 48 שעות מקבלים הרכב צוות ולוח זמנים משוער

ספרו לנו על הפרויקט

מעדיפים לדבר קודם? קבעו שיחה של 30 דקות