כיסוי קוד עם Bazel

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

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

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

יצירת דוח כיסוי

הכנה

תהליך העבודה הבסיסי ליצירת דוחות כיסוי מחייב את הדברים הבאים:

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

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

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

כברירת מחדל, Bazel מנסה להתאים לחבילות היעד, ומדפיסה את המסנן הרלוונטי כהודעה ב-INFO.

הכיסוי פועל

כדי להפיק דוח כיסוי, יש להשתמש ב-bazel coverage --combined_report=lcov [target]. אפשרות זו מפעילה את הבדיקות של היעד ויוצרת דוחות כיסוי בפורמט lcov לכל קובץ.

בסיום, Bazel מבצעת פעולה שאוספת את כל קובצי הכיסוי המוזגים, וממזגת אותם לקובץ אחד, שנוצר בסופו של דבר במסגרת $(bazel info output_path)/_coverage/_coverage_report.dat.

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

הסיקור המוצג

הפלט של דוח הסיקור הוא רק בפורמט lcov שאינו קריא לבני אדם. מכאן, אנחנו יכולים להשתמש בכלי השירות genhtml (חלק מפרויקט lcov) כדי להפיק דוח שאפשר לצפות בו בדפדפן אינטרנט:

genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"

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

כדי להציג את התוצאה, פשוט פותחים את הקובץ index.html שנוצר בספריית genhtml בכל דפדפן אינטרנט.

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

ביצוע מרחוק

להרצה עם ביצוע בדיקה מרחוק יש כרגע מספר נקודות:

  • לא ניתן עדיין להריץ מרחוק את פעולת השילוב של הדוח. הסיבה לכך היא ש-Bazel לא מתייחסת לקובצי הפלט של הכיסוי כחלק מהתרשים שלה (עיינו בבעיה הזו), ולכן אינה יכולה להתייחס אליהם כראוי בתור קלט לשילוב הפעולה. כדי לפתור את הבעיה, צריך להשתמש ב---strategy=CoverageReport=local.
    • הערה: במקום זאת, ייתכן שיהיה צורך לציין משהו כמו --strategy=CoverageReport=local,remote, אם Bazel מוגדר לנסות את local,remote, בשל האופן שבו Bazel פותרת אסטרטגיות.
  • כמו כן, לא ניתן להשתמש ב--remote_download_minimal ובדגלים דומים כתוצאה מהמוצר הקודם.
  • Bazel לא יוכל כרגע ליצור פרטי כיסוי אם הבדיקות נשמרו במטמון בעבר. כדי לעקוף את הבעיה, אפשר להגדיר את --nocache_test_results באופן ספציפי להרצה של כיסויים, אבל כמובן, העלות של בדיקות זו כרוכה בעלויות גבוהות.
  • --experimental_split_coverage_postprocessing וגם --experimental_fetch_all_coverage_outputs
    • בדרך כלל הכיסוי פועל כחלק מפעולת הבדיקה, לכן כברירת מחדל לא נוכל לקבל את כל הכיסוי בחזרה כפלט של ההפעלה מרחוק כברירת מחדל. הסימונים האלה עוקפים את ברירת המחדל ומשיגים את נתוני הכיסוי. לפרטים נוספים, ראו בעיה זו.

תצורה ספציפית לשפה

Java

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

Python

דרישות מוקדמות

להפעלת הכיסוי עם python יש כמה דרישות מוקדמות:

שימוש ב-width.py אחרי שינוי

דרך לעשות זאת היא באמצעותכללים_פיתון, כך תוכלו להשתמש בתכונהrequirements.txt הקובץ, הדרישות המפורטות בקובץ נוצרות כיעדים בזל באמצעותהתקנת pip_install כלל מאגר נתונים.

הערך requirements.txt צריך לכלול את הערך הבא:

git+https://github.com/ulfjack/coveragepy.git@lcov-support

לאחר מכן, יש להשתמש בקובץ rules_python, pip_install ובקובץ requirements.txt בקובץ WORKSPACE בתור:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "rules_python",
    url = "https://github.com/bazelbuild/rules_python/releases/download/0.5.0/rules_python-0.5.0.tar.gz",
    sha256 = "cd6730ed53a002c56ce4e2f396ba3b3be262fd7cb68339f0377a45e8227fe332",
)

load("@rules_python//python:pip.bzl", "pip_install")

pip_install(
   name = "python_deps",
   requirements = "//:requirements.txt",
)

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

load("@python_deps//:requirements.bzl", "entry_point")

alias(
    name = "python_coverage_tools",
    actual = entry_point("coverage"),
)

py_test(
    name = "test",
    srcs = ["test.py"],
    env = {
        "PYTHON_COVERAGE": "$(location :python_coverage_tools)",
    },
    deps = [
        ":main",
        ":python_coverage_tools",
    ],
)