למה TDD לא שולט בעולם?

ynigun

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

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

ynigun

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

עם זאת, פרקטיקה אחת שצברה תומכים נלהבים וגם כמה מבקרים נחרצים בשנים האחרונות היא פיתוח מונחה בדיקות (Test-Driven Development - TDD).

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

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

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

אז, בוא נראה... בלי סדר מסוים...

קטגוריות תגובה

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

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

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

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

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

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

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

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

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

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

פרשנות
מתוך למעלה מ-300 תגובות, נראה שיש לנו (לפחות) 10 סיבות מדוע אנשים חושבים ש-TDD לא השתלטה על העולם. מתוך אלה, כמה מהנ"ל קשורות ספציפית לפיתוח תוכנה (פנימי)? כמה הן תרבותיות/ארגוניות (חיצוני)? האם ניתן לארגן אותן לתת-קבוצות? אולי זה יעזור לפרש את התגובות...

מהחלוקה השרירותית שלי של עשרת הנושאים האלה (אנא נסה את שלך), מעניין ששניים בלבד נראים קשורים באופן מהותי לפרקטיקות הנדסת תוכנה ישירות (טבלה 1, עמודה 1: הנדסת תוכנה), בעוד ארבעה נראים מצומדים להתנגדות ארגונית (טבלה 1, עמודה 2: ארגוני) וארבעה נוספים נראים כחששות או חוסר ביטחון ביישום TDD (טבלה 1, עמודה 3: היסוס/ביטחון).

1715694476217.png


טבלה 1: נושאים מקובצים לפי חסמים נתפסים המונעים יישום TDD.

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

1715694492731.png

איור 1: נושאים מקובצים לפי חסמים נתפסים המונעים יישום TDD, בצורת ונ-יש ;)

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

העולם של מחר?
בעוד שמרבית התגובות של משתמשי טוויטר דנו בסיבות מדוע TDD לא השתלטה על העולם, היו כמה תגובות שהביעו אמונה ש-TDD תיאמץ בסופו של דבר באופן נרחב יותר. הנה כמה נושאים משותפים בין התגובות האלה:

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

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

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

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

שינוי תרבותי: כמה תגובות הציעו ששינוי תרבותי בקהילת פיתוח התוכנה יכול להניע את אימוץ TDD. ככל שיותר מפתחים מאמצים את TDD ומשתפים את יתרונותיה, היא יכולה להפוך לזרם המרכזי.

אינטגרציה רציפה: TDD מתאימה היטב לפרקטיקות פיתוח תוכנה מודרניות כמו אינטגרציה רציפה ומסירה רציפה (CI/CD). היא מבטיחה ששינויי קוד לא יוצרים נסיגות וקלים יותר לשילוב בבסיס הקוד הקיים.

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

יוזמות חינוכיות: המשיבים הציעו גם שחינוך והכשרה יכולים למלא תפקיד באימוץ הנרחב יותר של TDD. ככל שיותר מפתחים נחשפים ל-TDD דרך תוכניות חינוך או הכשרה פורמליות, השימוש בה יכול לגדול.

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

סיכום

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

אולי זה נותן לנו רמז היכן טמונה הסיבה האמיתית מדוע TDD עדיין לא השתלטה על העולם.

מה הלאה עבור TDD?
למדתי הרבה מהתגובות לשאלות של דייב. אולי תיבת התהודה של CD שלי גרמה לי להאמין ש-TDD בדרכה הטובה להיות מאומצת כפרקטיקת best practice בתעשייה. אך כשאנו שואלים את הקהילה הרחבה יותר, נראה ש-TDD נותרת פרקטיקה מקטבת בעולם פיתוח התוכנה, כאשר חלק מהמפתחים משבחים את מעלותיה ואחרים מטילים ספק בישימותה.

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

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

כמתרגלים של CD אנו יכולים לקחת את התובנות מנושאים אלה ולטפל בהם במקומות העבודה, בהכשרה ובצוותים שלנו - ואז אולי, יום אחד, TDD סוף סוף תשתלט על העולם!
 

ynigun

משתמש סופר מקצוען
הנדסת תוכנה
למי שרוצה להעמיק בנושא יותר
יש כאן בחור שנתן הרצאה בו מדבר בגנות של TDD
ואז באו חסידי הTDD ועשו איתו סדרת מפגשים בו ניסו להחזיר אותו בתשובה
ובו הם דנים לעומק בנושאים שונים ומציגים את כל הצדדים
https://martinfowler.com/articles/is-tdd-dead

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

ynigun

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

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

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

יש עוד מעלות שעליהם אפשר להתווכח וזה משתנה מפרוייקט לפרוייקט
חסידי הTDD טענים שלכתוב קוד שניתן לבדיקה באופן מבודד מוביל למבנה של קוד יותר בריא ויותר נח לאחוז ראש מה הקוד עושה כשהוא מפורק לגורמים קטנים וגם יותר קל לדיבוג בהמשך.
בנקודה הזאת יש חולקים ואומרים שזה סתם גורם לסרבול.
והתשובה היא "זה תלוי" (תלוי בפרוייקט, תלוי במפתח וכו')

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

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

C:
func isHoliday() bool {
    currentTime := time.Now()
    currentYear, currentMonth, currentDay := currentTime.Date()

    // Check for New Year's Day
    if currentMonth == time.January && currentDay == 1 {
        return true
    }

    // Check for Christmas Day
    if currentMonth == time.December && currentDay == 25 {
        return true
    }

    // Check for Hanukkah (assuming it starts on December 10th)
    if currentMonth == time.December && currentDay >= 10 && currentDay <= 18 {
        return true
    }

    // Check for Passover (assuming it starts on April 15th)
    if currentMonth == time.April && currentDay >= 15 && currentDay <= 22 {
        return true
    }

    // Check for Kwanzaa (assuming it starts on December 26th)
    if currentMonth == time.December && currentDay >= 26 && currentDay <= 31 {
        return true
    }

    // Add more holiday checks as needed

    return false
}

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

C:
type Holiday struct {
    Name      string
    StartDate time.Time
    EndDate   time.Time
}

func isHoliday() bool {
    currentTime := time.Now()
    holidays := GetHolidaysFromDB()
    for _, holiday := range holidays {
        if date.Equal(holiday.StartDate) || date.Equal(holiday.EndDate) ||
            (date.After(holiday.StartDate) && date.Before(holiday.EndDate)) {
            return true
        }
    }

    return false
}

ועכשיו לעשות לזה טסטים נהיה סרט
(אפשר להוסיף תרחיש שבהתחלה לקחנו בחשבון רק חגים עם יום אחד ואחר כך גילינו שיש חגים של שבוע)

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

C:
type Holiday struct {
    Name      string
    StartDate time.Time
    EndDate   time.Time
}

func isHoliday(date time.Time, holidays []Holiday) bool {
    for _, holiday := range holidays {
        if date.Equal(holiday.StartDate) || date.Equal(holiday.EndDate) ||
            (date.After(holiday.StartDate) && date.Before(holiday.EndDate)) {
            return true
        }
    }

    return false
}

ועכשיו קל לכתוב לזה טסטים אוטומטים שמכסים את כל התרחישים

C:
package main

import (
    "testing"
    "time"
)

func TestIsHoliday(t *testing.T) {
    // Define a list of holidays for testing
    holidays := []Holiday{
        {
            Name:      "New Year's Day",
            StartDate: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC),
            EndDate:   time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC),
        },
        {
            Name:      "Hanukkah",
            StartDate: time.Date(2023, time.December, 10, 0, 0, 0, 0, time.UTC),
            EndDate:   time.Date(2023, time.December, 18, 0, 0, 0, 0, time.UTC),
        },
        {
            Name:      "Christmas Day",
            StartDate: time.Date(2023, time.December, 25, 0, 0, 0, 0, time.UTC),
            EndDate:   time.Date(2023, time.December, 25, 0, 0, 0, 0, time.UTC),
        },
    }

    // Test cases
    testCases := []struct {
        name     string
        date     time.Time
        expected bool
    }{
        {
            name:     "Holiday - New Year's Day",
            date:     time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC),
            expected: true,
        },
        {
            name:     "Holiday - Hanukkah Start",
            date:     time.Date(2023, time.December, 10, 0, 0, 0, 0, time.UTC),
            expected: true,
        },
        {
            name:     "Holiday - Hanukkah Middle",
            date:     time.Date(2023, time.December, 15, 0, 0, 0, 0, time.UTC),
            expected: true,
        },
        {
            name:     "Holiday - Hanukkah End",
            date:     time.Date(2023, time.December, 18, 0, 0, 0, 0, time.UTC),
            expected: true,
        },
        {
            name:     "Holiday - Christmas Day",
            date:     time.Date(2023, time.December, 25, 0, 0, 0, 0, time.UTC),
            expected: true,
        },
        {
            name:     "Non-Holiday",
            date:     time.Date(2023, time.July, 15, 0, 0, 0, 0, time.UTC),
            expected: false,
        },
    }

    // Run test cases
    for _, tc := range testCases {
        t.Run(tc.name, func(t *testing.T) {
            result := isHoliday(tc.date, holidays)
            if result != tc.expected {
                t.Errorf("Expected %v but got %v", tc.expected, result)
            }
        })
    }
}


לטענת חסידי הTDD עכשיו יש לנו קוד יציב שאפשר לעשות בו שינויים בבטחון והקוד נחשב "נקי"
ושהתהליך לא לוקח הרבה יותר זמן כי אמנם צריך לכתוב יותר שורות קוד אבל רוב הזמן אנחנו חושבים והביצועים לא נמדדים בכמה שורות קוד צריך לכתוב.
אבל מי צד שני יש מי שיאמר שזה מסרבל את הכתיבה ושצריך להעביר את הפרמטרים לפעמים דרך 2-3 שכבות ושלדעתם זה רק נראה יותר מסורבל (במקרה של תאריך זה עוד בסדר יש מקרים שזה מסתבך יותר), ואמנם לרוב לא מוסיף הרבה זמן פיתוח כשכותבים את הקוד הראשוני אבל אם אנחנו רוצים לעשות עכשיו שינוי ובמקום לשים תאריך ושעה התחלה וסיום של החג אנחנו רוצים שיהיה רק תאריך עגול אז אנחנו עכשיו צריכים ולעבור ולשנות את כל הטסטים ועל שינוי של שורת קוד אחת צריך לשנות עשרות שורות קוד של טסטים (יותר מצוי שהשינוי יהיה הפוך אבל העיקרון מובן).
על זה התשובה היא שבסוף זה עניין של אומנות שנרכשת עם הזמן איך לעשות את הטסטים בצורה שלא יחזרו על עצמם ושלא יהיה סרט לשנות שורת קוד וגם שבאמת זה שווה את כל הכאב ראש ושאם באמת רוצים לעשות שינוי במשהו עמוק במבנה של הקוד נצטרך לעשות הרבה שינויים בטסטים אבל נוכל לעשות את זה בבטחון בפרט ששינוים כאלו זה מקום מועד לפורענות.
 

אולי מעניין אותך גם...

הפרק היומי

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


תהילים פרק יא

א לַמְנַצֵּחַ לְדָוִד בַּיהוָה חָסִיתִי אֵיךְ תֹּאמְרוּ לְנַפְשִׁי (נודו) נוּדִי הַרְכֶם צִפּוֹר:ב כִּי הִנֵּה הָרְשָׁעִים יִדְרְכוּן קֶשֶׁת כּוֹנְנוּ חִצָּם עַל יֶתֶר לִירוֹת בְּמוֹ אֹפֶל לְיִשְׁרֵי לֵב:ג כִּי הַשָּׁתוֹת יֵהָרֵסוּן צַדִּיק מַה פָּעָל:ד יְהוָה בְּהֵיכַל קָדְשׁוֹ יְהוָה בַּשָּׁמַיִם כִּסְאוֹ עֵינָיו יֶחֱזוּ עַפְעַפָּיו יִבְחֲנוּ בְּנֵי אָדָם:ה יְהוָה צַדִּיק יִבְחָן וְרָשָׁע וְאֹהֵב חָמָס שָׂנְאָה נַפְשׁוֹ:ו יַמְטֵר עַל רְשָׁעִים פַּחִים אֵשׁ וְגָפְרִית וְרוּחַ זִלְעָפוֹת מְנָת כּוֹסָם:ז כִּי צַדִּיק יְהוָה צְדָקוֹת אָהֵב יָשָׁר יֶחֱזוּ פָנֵימוֹ:
נקרא  9  פעמים

אתגר AI

חג מתן תורה • 1

ספירת העומר

לוח מודעות

למעלה