פרק קודם:
פייתון 25 - אסינכרוניות חלק בכלים לבדיקת איכות הקוד רצים ומוודאים שהקוד שכתבנו אכן עושה את מה שרצינו,
שכתבנו אותו ללא בעיות לוגיות וכשלים שיכולים לגרום לתקלות.
יש מגוון רחב של כלים כאלו ואנחנו נתמקד בכלים שנקראים Static Code Analyzers
- כלים הרצים בצורה סטטית לפני ריצת הקוד שמוודאים שהקוד שלנו אכן תקין.
בפרקים הקודמים למדנו איך לכתוב קוד בצורה מיטבית בכל נושא.
בכל פרוייקט שהוא - לאט לאט - נערמות לנו שורות על גבי שורות של קוד.
זה יוצר לנו בעיה:
עין אנושית צריכה לעבור על כל הקוד, לחפש בעיות ולתקן אותם.
המתכנתים שכתבו את הקוד לא תמיד יימצאו את כל הבעיות בעצמם - זו הבעיה בכתיבת קוד.
אז כמו כתיבת ספר - עורך ועמיתים נוספים עוברים על הכתוב ומוודאים שאין בעיות.
בשפה המקצועית זה נקרא Code Review
- בדיקת הקוד.
בשלב הזה גם המתכנתים שכתבו וגם המתכנתים שייבדקו את הקוד הולכים לעבור עליו שוב.
זהו שלב חשוב ולמרות שיש לנו כלים אוטומטיים - כדאי לבצע את השלב הזה.
אז מה הבעיה כאן אם כמות אנשים נכבדת עוברת על הקוד ומוודא שהכל תקין?
למשל בעיות כתיב פשוטות שיכולות לפגוע:
רוב הכלים האוטומטיים כבר יודעים לזהות כשלים כאלו.
1 | def Functon(): |
כדי לתקן את זה נוצרו כלים אוטומטיים שיכולים לבצע כל מיני סוגי בדיקות.
אז מה אנחנו צריכים לבדוק?
1 | a= 1 + 2-3* 2 |
כלי פורמט ייתקן לנו את זה מיד ל:
1 | a = 1 + 2 - 3 * 2 |
הצרה הקלאסית ביותר של מתכנתי פייתון זה הזחות או רווחים.
1 | def function(): |
Code Smell
זהו מונח לכל קוד היכול להביע פוטנציאל לבעיות.
זוהי ראייה מאוד סובייקטיבית כי בהתאם לסטנדרטים של המתכנתים והמתודולוגיות שלהם - הם יכולים לראות בקוד מסוים כקוד בעייתי או קוד לא בעייתי.
קוד נפוץ שמעלה תהיות:
הכלים האוטומטיים לא תמיד מתריעים על כך - כדי לא לתייג פונקציות לא בעיות כבעלי כשלים.
בדרך כלל אנחנו נרצה לזהות בעיות פוטנציאליות כגון:
נרצה למצוא את כלל הכשלים הלוגיים לפני שנריץ את הקוד.
באגים אבטחתיים
בין אם זה שימוש בפונקציות ישנות, קוד לא מאובטח או חיבור לא מוצפן אנחנו נרצה לזהות כשלים אבטחתיים בקוד שלנו.
קוד שלא בשימוש
בדרך כלל גם ה-IDE
שאנחנו משתמשים בו יתריע על קוד שלא בשימוש,
אך גם עבודת הלינטרים היא לבצע את הבידקות האלו.
כלים לבדיקת הפונקציונליות הבסיסית
בפרק הזה לא נתמקד בהם - אלו כלים שמריצים בדיקות אוטומטיות על לוגיקת הקוד שלנו ומוודאה שהיא עושה אכן את מה שהיא אמורה לעשות.
יצאנו לנו לראות את זה בפרקים הקודמים - בדרך כלל הכלים האלו מריצים טסטים שאנחנו כתבנו, דוגמא לזה תהיה:
1 | def Add(a , b): |
False Positive
. Multi threading
. כדי להוריד יש להשתמש ב-pip
:pip install pylint
להלן קוד תקול:
1 | def addFunc(): |
בכל שורה ל- a
, b
, c
זהו מהי הבעיה.
הבעיה ב-a
שהפונקציה לא מחזירה למרות שהקוד מצפה להחזרה.
הבעיה ב-b
שהפונקציה נכתבה עם שגיאת כתיב ולכן לא קיימת.
הבעיה ב-c
שזה חילוק באפס.
נשמור את הקוד התקול בקובץ myFile.py
ונריץ מה-Commandline
את הפקודה pylint
עם שם הקובץ בצורה הבאה:
1 | pylint myFile.py |
התובנות שקיבלנו מה-pylint
:
1 | myFile.py:8:0: C0304: Final newline missing (missing-final-newline) |
1 | myFile.py:1:0: C0114: Missing module docstring (missing-module-docstring) |
כדי להוסיף docstring
יש להוסיף:
1 | """ |
בתחילת הקובץ.
1 | myFile.py:1:0: C0103: Module name "myFile" doesn't conform to snake_case naming style (invalid-name) |
ניתן גם לשנות את זה בריצת הpylint
בהתאם לסטנדרטים שלנו.
ז”א לא חובה לעקוב אחרי כל שורה שהלינטרים מוציאים לנו אלה לדעת גם אנחנו כיצד הקוד שלנו צריך להיראות.
כדי לעשות רגקס משלנו לשם הקובץ נוכל להריץ אותו עם הפרמטר:
1 | pylint myFile.py --module-rgx=.* |
Doc string
על הפונקציה.1 | myFile.py:1:0: C0116: Missing function or method docstring (missing-function-docstring) |
במידת הצורך ניתן לבטל גם את זה:
1 | pylint myFile.py --errors-only |
האופציה --errors-only
נותנת לנו רק שגיאות לוגיות ולכן כדאי להתחיל רק עם זה.
1 | myFile.py:1:0: C0103: Function name "addFunc" doesn't conform to snake_case naming style (invalid-name) |
1 | myFile.py:4:0: E1111: Assigning result of a function call, where the function has no return (assignment-from-no-return) |
אין ערך החזרה מהפונקציה ואנחנו מצפים לזה, כעת שהוא גילה לנו את זה אנחנו יכולים לחזור לקוד ולתקן!
1 | myFile.py:6:4: E0602: Undefined variable 'AddFunc' (undefined-variable) |
שימו לב שהכלי pylint
לא הודיע לנו על חילוק באפס!
כל כלי שבא לעזור לנו לפתח מגיע עם סט יכולות מובנה ולא תמיד הכלים מכסים את כלל התרחישים.
לכן אני ממליץ לקחת את הכלים בערבון מוגבל ולהשתמש בהם ככלי עזר ולא כתחליף להרצת סט בדיקות מקיף.pylint
הוא אחד מהכלים שייעזרו לנו לעלות את איכות הקוד אבל זה לא הכלי היחידי!
ניתן למצוא מידע כאן:
Pylint Docs
הריצו את ה-pylint
עם הרמה - HIGH
.
הריצו את הכלי על תיקייה פרט לקובץ בשם dontrun.py
הריצו את הכלי עם הגבלת כמות פרמטרים לפונקציה - 5 פרמטרים מקסימום
פתרונות:
pylint --confidence HIGH
pylint dontrun.py --ignore dontrun.py
pylint anotherFile.py --max-args 5
Ruff
הוא כמו PyLint
אך הרבה הרבה יותר מהיר!
https://github.com/charliermarsh/ruff
אחרי שלמדנו את עקרונות הלינטינג מומלץ לעבור לספריה הזו מכיוון שהיא הרבה יותר זרירה מספריות אחרות.
הכלי Bandit
ייעזור לנו לגלות בעיות אבטחיות בסקריפטים.
להלן קוד:
1 | import os |
כדי להריץ את הכלי נוכל לתת לו קובץ והוא ייעבור עליו:
bandit myFile.py
התוצאה:
1 |
|
subprocess
.1 | import subprocess |
הרצה של סקריפטים או כלים חיצוניים לסקריפט שלנו אף פעם לא מוודאים שמה שיירוץ זה באמת מה שהתכוונו אליו.
דרך החלפה האקרים מיומנים יכולים להשתיל קוד זדוני מבלי שנשים לב.
איך פותרים את הבעיה הספציפית הזו?
בעדיפות לבצע import
או בדיקת Checksum
לכלים חיצוניים שאנחנו לא סומכים עליהם.
1 | exec(open(scriptToRun).read()) |
הפונקציה exec
מקבלת טקסט חופשי ומריצה אותו.
במידה והטקסט הזה הוא קוד זדוני אז אנחנו נריץ בצורה עיוורת קוד שמטרתו להרוס ולפגוע.
אל תשמשו בזה אף פעם!
גם os.startfile(scriptToRun)
וגם p = subprocess.run(scriptToRun)
מריצים תהליך בשני פונקציות שורות.
הראשון יריץ תהליך ללא יכולת לקטוע אותו, שימו לב שבצורה השנייה יש לנו השמה למשתנה.
השני יתריע לנו על כך שאנחנו לא מבצעים בדיקה מה אנחנו מריצים.
בגלל השימוש ב-Environment Variable
זה מלה את הסיכון של הסקריפט הזה להריץ קוד זדוני.
כאשר אתם כותבים קוד שיירוץ בשרת כלשהו כמו Django
תשימו לב לכל קלט שאתם מקבלים באופן חיצוני.
כמו כן אם אתם כותבים ספריות ציבוריות אל תשמשו בצורת קוד שיכולה להיות מוחלפת מבלי שתשימו לב כגון subprocess
או - exec
.
אולי הכוונה שלכם טובה אבל קוד לא מאובטח ינוצל לרעה בסופו של דבר.
IDE
- Integrated Development Environment
אלו כלים שנותנים לכם הכל.
זאת אומרת שלינטרים וכלים אוטומטיים חלקיים יהיו כבר מובנים כגון כלי בדיקה.
מי שמשתמש בכלי המדהים הזה יכול לערוך את ההגדרות שלו:
Configure PyCharm
ב-VS Code
יש לנו הרחבות שנותנות לנו יכולות שונות.
למשל כמה הרחבות שלי יש:
הצגתי לכם 2 כלים פשוטים שמכסים לכם חלק מהתרחישים.
יש כלים נוספים - מהירים יותר, ומכסים תרחישים שונים שיכולים לעזור לכם:
הפלייק 8 ייעזור לכם בפרמוט וסטייל של הקוד:
בודק טייפים בצורה מהימנה.
פורמטר לקוד - מהיר ויעיל
בפרק הבא נעבור על סט כלים לבדיקות פונקציונליות הנקראים טסטים!
נראה איך כותבים טסטים נכונים ברמה הקטנה של הקוד, איך מתאימים קוד לטסטים ואיך פייתון כשפת סקריפט עוזרת לנו בעולם הטסטים גם בטכנולוגיות אחרות.