يقدّم Bazel أمرًا فرعيًا بعنوان coverage
لإنشاء تقارير تغطية الرمز في المستودعات التي يمكن اختبارها باستخدام bazel coverage
. ونظرًا للخصوصيات المميّزة للمنظومة المتكاملة المتنوعة للغات، لا يُعتبر من السهل تنفيذ هذا العمل في مشروع معيّن.
توثّق هذه الصفحة العملية العامة لإنشاء تقارير التغطية وعرضها، كما تعرض بعض الملاحظات بلغات معيّنة للغات التي تكون إعداداتها معروفة. ومن الأفضل قراءة القسم العام أولاً، ثم القراءة عن متطلبات لغة معيّنة. لاحظ أيضًا قسم التنفيذ عن بُعد الذي يتطلب بعض الاعتبارات الإضافية.
على الرغم من إمكانية إجراء الكثير من عمليات التخصيص، يركّز هذا المستند على
إنشاء تقارير lcov
واستخدامها، وهو حاليًا
المسار الأكثر توافقًا.
إنشاء تقرير تغطية
الإعداد
يتطلب سير العمل الأساسي لإنشاء تقارير التغطية ما يلي:
- مستودع أساسي باستهدافات الاختبار
- سلسلة أدوات تم تثبيت أدوات تغطية اللغة بها
- ضبط "طريقة قياس&صحيح" صحيحة
والإعدادان السابقان يتكلمان لغة خاصة وبسيطة في الغالب، إلا أن النوع الثاني قد يكون أكثر صعوبة عند تنفيذ المشاريع المعقدة.
"الحاسبة"؛ تشير في هذه الحالة إلى أدوات التغطية التي يتم استخدامها
لهدف محدّد. ويسمح Bazel بتفعيل هذا الإعداد
لمجموعة فرعية معيّنة من الملفات باستخدام العلامة
--instrumentation_filter
، التي تحدّد فلترًا للأهداف التي يتم اختبارها
مع تفعيل الإعداد. لتفعيل قياس حالة الاختبارات، يجب استخدام علامة --instrument_test_targets
.
وفقًا للإعدادات التلقائية، يحاول Bazel مطابقة الحزمة(الحزم) المستهدَفة ويطبع الفلتر ذي الصلة كرسالة INFO
.
تغطية تغطية الركض
لإنشاء تقرير تغطية، استخدِم bazel coverage
--combined_report=lcov
[target]
. يؤدي ذلك إلى تنفيذ اختبارات
الهدف، وإنشاء تقارير التغطية بتنسيق lcov
لكل ملف.
بعد الانتهاء من إنشاء الفيديو، يُجري البازيل إجراءً يجمع كل ملفات التغطية التي تم إنتاجها، ثم يدمجها في ملف واحد، ثم يتم إنشاؤه أخيرًا ضمن $(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:
- برنامج ثنائي للبيزال يتضمن b01c859، الذي يجب أن يكون أيًّا من Bazel >3.0.
- نسخة معدّلة من تغطيتها.
استهلاك التغطية المعدّلة
لإجراء ذلك، يمكنك تنفيذ ذلك من خلال Rule_python، ما يوفّر إمكانية استخدام ملف requirements.txt
، ويتم بعد ذلك إنشاء المتطلبات المذكورة في الملف كأهداف bazel باستخدام قاعدة المستودع
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",
)
ويمكن بعد ذلك استهلاك متطلبات التغطية.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",
],
)
إذا كنت تستخدم سلسلة أدوات Python مزخرفة، بدلاً من إضافة اعتمادية التغطية
إلى كل هدف py_test
، يمكنك إضافة أداة التغطية إلى
ضبط سلسلة الأدوات.
ونظرًا لأن قاعدة pip_install تعتمد على سلسلة أدوات Python، لا يمكن استخدامها لجلب وحدة coverage
.
بدلاً من ذلك، يمكنك إضافة WORKSPACE
على سبيل المثال.
http_archive(
name = "coverage_linux_x86_64"",
build_file_content = """
py_library(
name = "coverage",
srcs = ["coverage/__main__.py"],
data = glob(["coverage/*", "coverage/**/*.py"]),
visibility = ["//visibility:public"],
)
""",
sha256 = "84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3",
type = "zip",
urls = [
"https://files.pythonhosted.org/packages/74/0d/0f3c522312fd27c32e1abe2fb5c323b583a5c108daf2c26d6e8dfdd5a105/coverage-6.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
],
)
بعد ذلك، اضبط سلسلة أدوات python على سبيل المثال.
py_runtime(
name = "py3_runtime_linux_x86_64",
coverage_tool = "@coverage_linux_x86_64//:coverage",
files = ["@python3_9_x86_64-unknown-linux-gnu//:files"],
interpreter = "@python3_9_x86_64-unknown-linux-gnu//:bin/python3",
python_version = "PY3",
)
py_runtime_pair(
name = "python_runtimes_linux_x86_64",
py2_runtime = None,
py3_runtime = ":py3_runtime_linux_x86_64",
)
toolchain(
name = "python_toolchain_linux_x86_64",
exec_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
toolchain = ":python_runtimes_linux_x86_64",
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)