Bazel সঙ্গে কোড কভারেজ

Bazel একটি coverage সাব-কমান্ড বৈশিষ্ট্যযুক্ত রিপোজিটরিগুলিতে কোড কভারেজ রিপোর্ট তৈরি করতে যা bazel coverage দিয়ে পরীক্ষা করা যেতে পারে। বিভিন্ন ভাষার ইকোসিস্টেমের আইডিওসিঙ্ক্রাসিসের কারণে, একটি প্রদত্ত প্রকল্পের জন্য এই কাজটি করা সবসময় তুচ্ছ নয়।

এই পৃষ্ঠাটি কভারেজ রিপোর্ট তৈরি এবং দেখার জন্য সাধারণ প্রক্রিয়া নথিভুক্ত করে, এবং ভাষাগুলির জন্য কিছু ভাষা-নির্দিষ্ট নোটও রয়েছে যার কনফিগারেশন সুপরিচিত। প্রথমে সাধারণ বিভাগটি পড়ে এবং তারপর একটি নির্দিষ্ট ভাষার প্রয়োজনীয়তা সম্পর্কে পড়ার মাধ্যমে এটি সবচেয়ে ভালো হয়। রিমোট এক্সিকিউশন বিভাগটিও নোট করুন, যা কিছু অতিরিক্ত বিবেচনার প্রয়োজন।

যদিও অনেক কাস্টমাইজেশন সম্ভব, এই ডকুমেন্টটি lcov রিপোর্ট তৈরি এবং ব্যবহার করার উপর ফোকাস করে, যা বর্তমানে সবচেয়ে ভাল-সমর্থিত রুট।

একটি কভারেজ রিপোর্ট তৈরি করা

প্রস্তুতি

কভারেজ রিপোর্ট তৈরির জন্য মৌলিক কর্মপ্রবাহের জন্য নিম্নলিখিতগুলি প্রয়োজন:

  • পরীক্ষার লক্ষ্য সহ একটি মৌলিক সংগ্রহস্থল
  • ভাষা-নির্দিষ্ট কোড কভারেজ সরঞ্জাম ইনস্টল করা একটি টুলচেইন
  • একটি সঠিক "ইনস্ট্রুমেন্টেশন" কনফিগারেশন

আগের দুটি ভাষা-নির্দিষ্ট এবং বেশিরভাগই সহজবোধ্য, তবে পরবর্তীটি জটিল প্রকল্পগুলির জন্য আরও কঠিন হতে পারে।

এই ক্ষেত্রে "ইনস্ট্রুমেন্টেশন" একটি নির্দিষ্ট লক্ষ্যের জন্য ব্যবহৃত কভারেজ সরঞ্জামগুলিকে বোঝায়। Bazel --instrumentation_filter পতাকা ব্যবহার করে ফাইলের একটি নির্দিষ্ট উপসেটের জন্য এটি চালু করার অনুমতি দেয়, যা ইনস্ট্রুমেন্টেশন সক্ষম করে পরীক্ষা করা লক্ষ্যগুলির জন্য একটি ফিল্টার নির্দিষ্ট করে। পরীক্ষার জন্য ইন্সট্রুমেন্টেশন সক্ষম করতে, --instrument_test_targets পতাকা প্রয়োজন।

ডিফল্টরূপে, বেজেল লক্ষ্য প্যাকেজ(গুলি) মেলানোর চেষ্টা করে এবং প্রাসঙ্গিক ফিল্টারটিকে একটি 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 কার্যকর করা হয়েছে।

ফলাফল দেখতে, যেকোনো ওয়েব ব্রাউজারে genhtml ডিরেক্টরিতে উত্পাদিত index.html ফাইলটি খুলুন।

genhtml টুল বা lcov কভারেজ ফরম্যাট সম্পর্কে আরও সাহায্য এবং তথ্যের জন্য, lcov প্রজেক্ট দেখুন।

দূরবর্তী মৃত্যুদন্ড

রিমোট টেস্ট এক্সিকিউশনের সাথে চলমান বর্তমানে কয়েকটি সতর্কতা রয়েছে:

  • রিপোর্ট সংমিশ্রণ কর্ম এখনও দূরবর্তীভাবে চালানো যাবে না. এর কারণ হল Bazel কভারেজ আউটপুট ফাইলগুলিকে তার গ্রাফের অংশ হিসাবে বিবেচনা করে না ( এই সমস্যাটি দেখুন), এবং সেইজন্য সেগুলিকে সংমিশ্রণ কর্মের ইনপুট হিসাবে সঠিকভাবে বিবেচনা করতে পারে না৷ এই বিষয়ে কাজ করতে, --strategy=CoverageReport=local ব্যবহার করুন।
    • দ্রষ্টব্য: Bazel যেভাবে কৌশলগুলি সমাধান করে তার কারণে যদি Bazel local,remote চেষ্টা করার জন্য সেট আপ করা হয় তবে --strategy=CoverageReport=local,remote এর মত কিছু নির্দিষ্ট করার প্রয়োজন হতে পারে।
  • --remote_download_minimal এবং অনুরূপ পতাকাগুলিও পূর্বের ফলাফল হিসাবে ব্যবহার করা যাবে না।
  • Bazel বর্তমানে কভারেজ তথ্য তৈরি করতে ব্যর্থ হবে যদি পরীক্ষাগুলি আগে ক্যাশ করা হয়। এটিকে ঘিরে কাজ করার জন্য, --nocache_test_results বিশেষভাবে কভারেজ রানের জন্য সেট করা যেতে পারে, যদিও এটি অবশ্যই পরীক্ষার সময়ের পরিপ্রেক্ষিতে একটি ভারী খরচ বহন করে।
  • --experimental_split_coverage_postprocessing এবং --experimental_fetch_all_coverage_outputs
    • সাধারণত কভারেজ পরীক্ষা কর্মের অংশ হিসাবে চালানো হয়, এবং তাই ডিফল্টরূপে, আমরা ডিফল্টরূপে রিমোট এক্সিকিউশনের আউটপুট হিসাবে সমস্ত কভারেজ ফিরে পাই না। এই পতাকাগুলি ডিফল্টকে ওভাররাইড করে এবং কভারেজ ডেটা প্রাপ্ত করে। আরো বিস্তারিত জানার জন্য এই সমস্যা দেখুন.

ভাষা-নির্দিষ্ট কনফিগারেশন

জাভা

জাভা ডিফল্ট কনফিগারেশন সহ বাক্সের বাইরে কাজ করা উচিত। বেজেল টুলচেইনগুলিতে JUnit সহ দূরবর্তী সম্পাদনের জন্য প্রয়োজনীয় সমস্ত কিছু রয়েছে।

পাইথন

পূর্বশর্ত

পাইথনের সাথে কভারেজ চালানোর কিছু পূর্বশর্ত রয়েছে:

পরিবর্তিত coverage.py ব্যবহার করা

এটি করার একটি উপায় হল rules_python এর মাধ্যমে, এটি একটি 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",
)

Coverage.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",
    ],
)

আপনি যদি একটি হারমেটিক পাইথন টুলচেন ব্যবহার করেন, তাহলে প্রতিটি 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",
    ],
)

তারপরে আপনার পাইথন টুলচেনকে যেমন কনফিগার করুন

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",
)