Code Coverage (কোড কভারেজ) একটি মেট্রিক যা দেখায় অ্যাপ্লিকেশনের সোর্স কোডের কত শতাংশ টেস্টিং চলাকালীন এক্সিকিউট হয়। এটি টেস্টের গুণমান নির্ধারণ করতে, অপরীক্ষিত এলাকা চিহ্নিত করতে এবং নতুন টেস্ট লেখার অগ্রাধিকার নির্ধারণে সহায়তা করে। Atlassian, 2025-এর মতে, সর্বোত্তম কভারেজ স্তর 70–80% — এই সীমার উপরে, টেস্টিং খরচ সুবিধাকে ছাড়িয়ে যেতে শুরু করে।
মূল বিষয়
Code Coverage (কোড কভারেজ) একটি পরিমাণগত মেট্রিক যা নির্ধারণ করে অ্যাপ্লিকেশনের সোর্স কোডের কোন অংশ টেস্টের সময় এক্সিকিউট হয়েছে। এটি শতাংশে প্রকাশ করা হয় এবং এক্সিকিউট হওয়া লাইন/ব্রাঞ্চের মোট সংখ্যার অনুপাত হিসাবে গণনা করা হয়। উচ্চ কভারেজ বাগের অনুপস্থিতি নিশ্চিত করে না, তবে অমীমাংসিত ত্রুটির ঝুঁকি হ্রাস করে।
কোড কভারেজ টিমকে সাহায্য করে: কোডের অপরীক্ষিত এলাকা খুঁজে পেতে, টেস্ট লেখার অগ্রাধিকার সম্পর্কে সিদ্ধান্ত নিতে, এবং CI/CD-তে টেস্টিং গুণমানের গতিশীলতা ট্র্যাক করতে। মোবাইল ডেভেলপমেন্টে, কভারেজ বিশেষ করে বিজনেস লজিক, ডেটা মডেল এবং রিপোজিটরি — যেসব লেয়ারে ত্রুটির সম্ভাবনা সবচেয়ে বেশি — সেগুলোর জন্য গুরুত্বপূর্ণ।
একটি সাধারণ ভুল ধারণা: “100% কভারেজ = নিখুঁত গুণমান”। বাস্তবে, 100% কভারেজ অত্যন্ত বিরল এবং প্রায়শই ভাসা ভাসা টেস্টের মূল্যে অর্জিত হয়। কার্যকরী কভারেজ শতাংশের প্রতিযোগিতা নয়, বরং গুরুত্বপূর্ণ পাথ এবং সীমান্তবর্তী অবস্থার কৌশলগত কভারেজ। কভারেজ টেস্টের গুণমান সম্পর্কে কিছু বলে না: একটি টেস্ট পাস করতে পারে কিন্তু ফলাফলের সঠিকতা যাচাই নাও করতে পারে।
Code Coverage-এর বেশ কয়েকটি মেট্রিক্স বিদ্যমান, প্রতিটি টেস্টিংয়ের বিভিন্ন দিক পরিমাপ করে। Line coverage (লাইন কভারেজ)是最 সরল মেট্রিক, যা এক্সিকিউট হওয়া কোড লাইনের শতাংশ দেখায়। Branch coverage (ব্রাঞ্চ কভারেজ) পরিমাপ করে কোন if-else এবং switch শাখাগুলো টেস্ট করা হয়েছে।
Line coverage প্রতিটি সোর্স কোড লাইনকে এক্সিকিউট বা না হিসাবে গণনা করে। যদি কোনো লাইনে শর্তাধীন অপারেটর বা লুপ থাকে, তাহলে লাইনটি এক্সিকিউট বিবেচিত হয় যদি নিয়ন্ত্রণ সেখানে পৌঁছায়, এমনকি সব শাখা প্রক্রিয়াকৃত না হলেও। এটি সবচেয়ে কম কঠোর মেট্রিক, তবে ভিজুয়াল মূল্যায়নের জন্য সবচেয়ে বোধগম্য।
Branch coverage মূল্যায়ন করে কোডের সব সম্ভাব্য শাখা টেস্ট করা হয়েছে কিনা। প্রতিটি if-else-এর জন্য উভয় শাখা বিবেচনা করা হয়: true এবং false। switch-এর জন্য, প্রতিটি case বিবেচনা করা হয়। Branch coverage লাইন কভারেজের চেয়ে বেশি কঠোর মেট্রিক হিসাবে বিবেচিত হয় এবং প্রায়শই অপরীক্ষিত পরিস্থিতি প্রকাশ করে।
| মেট্রিক | কী পরিমাপ করে | অর্জনের জটিলতা |
|---|---|---|
| Line | এক্সিকিউট হওয়া কোড লাইনের শতাংশ | কম |
| Branch | এক্সিকিউট হওয়া শাখার শতাংশ (if/else, switch) | মধ্যম |
| Function | কল করা ফাংশন এবং মেথডের শতাংশ | কম |
| Condition | লজিক্যাল উপ-অভিব্যক্তির শতাংশ (&&, ||) | উচ্চ |
Path coverage হল সবচেয়ে কঠোর মেট্রিক, যা একটি ফাংশনের সব সম্ভাব্য সংমিশ্রণ যাচাই করা প্রয়োজন। বাস্তবে, path coverage খুব কমই ব্যবহৃত হয় কারণ সংমিশ্রণের সংখ্যা দ্রুতগতিতে বেড়ে যায়: ১০টি শাখা বিশিষ্ট একটি ফাংশনের ১০২৪টি সম্ভাব্য পাথ থাকে।
মোবাইল ডেভেলপমেন্টে, প্ল্যাটফর্মের উপর নির্ভর করে Code Coverage পরিমাপের জন্য বিভিন্ন টুল ব্যবহার করা হয়। Android-এর জন্য মানক হল JaCoCo (Java Code Coverage), যা Gradle-এর সাথে সংহত হয় এবং ইউনিট টেস্ট ও ইন্সট্রুমেন্টেশন টেস্ট উভয়ই সমর্থন করে। iOS-এর জন্য Xcode-এ নির্মিত XCCov ব্যবহার করা হয়।
JaCoCo HTML, XML এবং CSV ফরম্যাটে রিপোর্ট তৈরি করে। HTML রিপোর্ট দৃশ্যত লাইন হাইলাইট করে: সবুজ — এক্সিকিউট, লাল — বাদ দেওয়া, হলুদ — আংশিক এক্সিকিউট। XML রিপোর্ট SonarQube এবং অন্যান্য কোড বিশ্লেষণ সিস্টেমের সাথে সামঞ্জস্যপূর্ণ। JaCoCo ক্লাস ফিল্টারিং সমর্থন করে: জেনারেটেড কোড, ডেটাবাইন্ডিং এবং BuildConfig বাদ দেওয়া যেতে পারে।
// build.gradle — JaCoCo কনফিগারেশন
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
// JaCoCo রিপোর্ট জেনারেট করা
task jacocoTestReport(type: JacocoReport) {
dependsOn 'testDebugUnitTest'
reports {
xml.enabled = true
html.enabled = true
}
}
XCCov কোড কভারেজ পরিমাপের জন্য Xcode-এ নির্মিত একটি টুল। এটি টেস্ট স্কিমে Gather coverage data-এর মাধ্যমে সক্রিয় করা হয়। XCCov Swift এবং Objective-C-এর জন্য কভারেজ সমর্থন করে, .xccovreport ফরম্যাটে রিপোর্ট তৈরি করে এবং xcodebuild -enableCodeCoverage YES-এর মাধ্যমে CI-এর সাথে সংহত হয়। ডেটা কনসোলে আউটপুট হয় এবং JSON-এ এক্সপোর্ট করা যেতে পারে।
কেন্দ্রীভূত কভারেজ মনিটরিংয়ের জন্য SonarQube (কোড গুণমান বিশ্লেষণ + কভারেজ), Codecov এবং Coveralls-এর মতো প্ল্যাটফর্ম ব্যবহার করা হয়। এই সার্ভিসগুলি JaCoCo এবং XCCov থেকে ডেটা একত্রিত করে, ট্রেন্ড, কোয়ালিটি গেট এবং PR মন্তব্যের মাধ্যমে GitHub/GitLab-এর সাথে ইন্টিগ্রেশন দেখায়।
Code Coverage উন্নত করার জন্য একটি পদ্ধতিগত পদ্ধতির প্রয়োজন: “শতাংশ বাড়ানো” নয়, বরং ঝুঁকি বন্ধ করা। প্রথম ধাপ হল JaCoCo বা XCCov রিপোর্ট বিশ্লেষণ করা — লাল (অকভারেজ) ক্লাস চিহ্নিত করা। অগ্রাধিকার: বিজনেস লজিক → রিপোজিটরি → ViewModel → UI কম্পোনেন্ট।
টেস্ট-চালিত ডেভেলপমেন্ট (TDD) স্বয়ংক্রিয়ভাবে উচ্চ কভারেজ নিশ্চিত করে, কারণ টেস্ট বাস্তবায়নের আগে লেখা হয়। প্রক্রিয়া: লাল (ব্যর্থ টেস্ট লেখা) → সবুজ (ন্যূনতম কোড লেখা) → রিফ্যাক্টর। TDD ডেভেলপারকে শৃঙ্খলাবদ্ধ করে, তাদের সীমান্তবর্তী ক্ষেত্র এবং ব্যতিক্রমী পরিস্থিতি কভার করতে বাধ্য করে যা প্রায়শই টেস্ট ছাড়া থাকে।
একটি প্যারামিটারাইজড টেস্ট ডজন ডজন সাধারণ টেস্ট প্রতিস্থাপন করে। JUnit এবং XCTest প্যারামিটারাইজেশন সমর্থন করে: JUnit 5-এ @ParameterizedTest, XCTest-এ XCTestCase-এর সাথে testPerformanceExample। প্যারামিটারাইজেশন কোড পুনরাবৃত্তি ছাড়াই একাধিক ইনপুট ডেটা যাচাই করার অনুমতি দেয়, যা ব্রাঞ্চ এবং কন্ডিশন কভারেজ উল্লেখযোগ্যভাবে বাড়ায়।
// Kotlin-এ JUnit 5-এর সাথে প্যারামিটারাইজড টেস্ট
@ParameterizedTest
@ValueSource(strings = ["user@test.com", "admin@test.com", "test@example.com"])
fun `validate email returns true for valid addresses`(email: String) {
val result = EmailValidator.isValid(email)
Assertions.assertTrue(result)
}
সবচেয়ে সাধারণ ভুল হল টেস্টের গুণমান বিশ্লেষণ না করে শতাংশের পিছনে ছোটা। টিম টেস্টের জন্য টেস্ট লেখা শুরু করে: গেটার এবং সেটার চেক করা, বিভিন্ন স্তরে কভারেজ ডুপ্লিকেট করা, তুচ্ছ মেথড টেস্ট করা। এটি উচ্চ শতাংশ দেয় কিন্তু প্রকৃত গুণমান উন্নত করে না।
উচ্চ Code Coverage একটি মিথ্যা ধারণা তৈরি করতে পারে যে অ্যাপ্লিকেশনটি ভালভাবে টেস্ট করা হয়েছে। একটি টেস্ট কোডের একটি লাইন এক্সিকিউট করতে পারে কিন্তু ফলাফলের সঠিকতা যাচাই নাও করতে পারে। উদাহরণস্বরূপ: একটি টেস্ট ডিসকাউন্ট গণনা মেথড কল করে কিন্তু পরিমাণ চেক করে না — লাইন এক্সিকিউট হয়েছে, কভারেজ বেড়েছে, কিন্তু বাগ পাওয়া যায়নি।
একটি সাধারণ ভুল হল শুধুমাত্র “হ্যাপি পাথ” (happy path) টেস্ট করা এবং সীমান্তবর্তী ক্ষেত্র উপেক্ষা করা: খালি তালিকা, null মান, সর্বোচ্চ সংখ্যা, ভুল ফরম্যাট। বেশিরভাগ বাগ সীমানা এবং ব্যতিক্রমে ঘটে। Branch coverage বাদ দেওয়া শাখা চিহ্নিত করতে সাহায্য করে, কিন্তু সীমান্তবর্তী মান যাচাইয়ের নিশ্চয়তা দেয় না।
মিউটেশন টেস্টিং হল টেস্টের গুণমান মূল্যায়নের একটি পদ্ধতি যেখানে সোর্স কোডে মিউটেশন (কৃত্রিম ত্রুটি) প্রবেশ করানো হয় এবং দেখা হয় টেস্ট ব্যর্থ হয় কিনা। Pitest Java এবং Kotlin-এর জন্য একটি জনপ্রিয় মিউটেশন টেস্টিং টুল। যদি টেস্ট কোনো মিউটেশনে ব্যর্থ না হয়, তাহলে তারা সেই শর্তটি যাচাই করছে না।
Pitest মিউট্যান্ট তৈরি করে — সোর্স কোডের পরিবর্তিত কপি যেখানে, উদাহরণস্বরূপ, > প্রতিস্থাপিত হয়েছে >= দিয়ে, true false দিয়ে, বা একটি মেথড কল মুছে ফেলা হয়েছে। তারপর প্রতিটি মিউট্যান্টের জন্য টেস্ট চালানো হয়। যদি টেস্ট পাস করে — মিউট্যান্ট বেঁচে গেছে, অর্থাৎ টেস্ট সেই পরিস্থিতি কভার করে না। যদি টেস্ট ব্যর্থ হয় — মিউট্যান্ট মারা গেছে, টেস্ট সঠিক।
// build.gradle — Pitest কনফিগারেশন
plugins {
id 'info.solidsoft.pitest' version '1.15.0'
}
pitest {
targetClasses = ['com.example.app.*']
targetTests = ['com.example.app.*Test']
threads = 4
outputFormats = ['HTML', 'XML']
mutationThreshold = 80
coverageThreshold = 85
}
Pitest বিভিন্ন ধরনের মিউটেশন সমর্থন করে: শর্তাধীন অপারেটর পরিবর্তন (== → !=, < → <=), মেথড কল মুছে ফেলা, রিটার্ন মান প্রতিস্থাপন (true → false), গাণিতিক অপারেশন পরিবর্তন (+ → -), ইনক্রিমেন্ট মিউটেশন (i++ → i--)। যত বেশি ধরনের মিউটেশন টেস্ট দ্বারা মারা যায়, টেস্ট সেট তত বেশি নির্ভরযোগ্য।
লক্ষ্য মিউটেশন স্কোর ৮০% এবং তার উপরে। এর মানে হল ৮০% কৃত্রিম ত্রুটি টেস্ট দ্বারা সনাক্ত করা হয়। ৯০% কোড কভারেজ নিশ্চিত করে না যে টেস্ট বাগ খুঁজে পায় — মিউটেশন টেস্টিং আরও বস্তুনিষ্ঠ মূল্যায়ন প্রদান করে। Pitest CI-তে কোয়ালিটি গেট হিসেবে সংহত করা যেতে পারে, মিউটেশন স্কোর সীমার নিচে নেমে গেলে বিল্ড ব্লক করে।
CI/CD-তে Code Coverage-এর স্বয়ংক্রিয় নিয়ন্ত্রণের জন্য কোয়ালিটি গেট ব্যবহার করা হয় — সীমা মান, যা লঙ্ঘন করলে বিল্ড অস্থির হিসাবে চিহ্নিত হয় বা প্রত্যাখ্যান করা হয়। SonarQube মেট্রিক্সের সংমিশ্রণের ভিত্তিতে কোয়ালিটি গেট কনফিগার করার অনুমতি দেয়: কভারেজ (≥৮০%), বাগের সংখ্যা, দুর্বলতা এবং ডুপ্লিকেট কোড।
GitHub Actions-এ, Code Coverage অ্যাকশন ধাপের মাধ্যমে সংহত হয়: কভারেজ সহ টেস্ট চালান → Codecov-এ রিপোর্ট আপলোড করুন → সীমা চেক করুন। Codecov স্বয়ংক্রিয়ভাবে PR-এ কভারেজ ডিফ সহ মন্তব্য করে, দেখায় কোন লাইন পরিবর্তিত হয়েছে এবং কীভাবে এটি সামগ্রিক শতাংশকে প্রভাবিত করেছে। যদি কভারেজ কমে যায়, অতিরিক্ত টেস্ট না লেখা পর্যন্ত PR ব্লক করা হয়।
# GitHub Actions — Codecov-এ কভারেজ আপলোড করা
- name: Run Tests with Coverage
run: ./gradlew testDebugUnitTest jacocoTestReport
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
files: ./app/build/reports/jacoco/jacocoTestReport.xml
flags: unittests
fail_ci_if_error: true
- name: Check Coverage Threshold
run: |
coverage=$(grep -oP 'branchCoverage="\K[0-9.]+' report.xml)
if (( $(echo "$coverage < 80" | bc -l) )); then
echo "Coverage $coverage% is below 80% threshold"
exit 1
fi
JaCoCo এবং XCCov-এর HTML রিপোর্টে ভিজুয়াল কভারেজ হাইলাইটিং থাকে: সবুজ — এক্সিকিউট লাইন, লাল — এক্সিকিউট নয়। SonarQube অতিরিক্তভাবে ফাইল, ক্লাস, মেথড এবং লাইন স্তরে কভারেজ দেখায়, পাশাপাশি স্প্রেন্ট অনুসারে কভারেজ পরিবর্তনের ইতিহাস দেখায়। এটি রিফ্যাক্টরিং এবং টেস্ট যোগ করার বিষয়ে সিদ্ধান্ত নিতে সাহায্য করে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
মোবাইল প্রজেক্টের জন্য, বিজনেস লজিকের জন্য ৭০–৮০% এবং UI কম্পোনেন্টের জন্য ৫০–৬০% কভারেজ ভালো বলে বিবেচিত হয়। ৮০% এর উপরে, টেস্টিং খরচ সুবিধাকে ছাড়িয়ে যেতে শুরু করে। এটি মনে রাখা গুরুত্বপূর্ণ যে শতাংশ কোনো লক্ষ্য নয় বরং একটি সূচক, এবং বিভিন্ন মডিউলের বিভিন্ন লক্ষ্য স্তর থাকতে পারে।
Line Coverage দেখায় কতগুলি কোড লাইন এক্সিকিউট হয়েছে। Branch Coverage দেখায় কতগুলি শাখা (if-else, switch) টেস্ট করা হয়েছে। if-যুক্ত একটি লাইন এক্সিকিউট হতে পারে, কিন্তু শুধুমাত্র true শাখা টেস্ট করা হতে পারে, false নয়। Branch Coverage বেশি কঠোর এবং আরও বেশি বাদ দেওয়া পরিস্থিতি প্রকাশ করে।
CI/CD-তে, কভারেজ কোয়ালিটি গেট-এর মাধ্যমে সংহত হয়: কভারেজ সীমার নিচে থাকলে বিল্ড ব্লক করা হয়। Android-এর জন্য JaCoCo + SonarQube ব্যবহার করা হয়, iOS-এর জন্য — xcodebuild -enableCodeCoverage সহ .xccovreport পার্সিং। GitHub Actions-এ Codecov-এর জন্য প্রস্তুত অ্যাকশন রয়েছে।
হ্যাঁ, JaCoCo স্ট্যান্ডার্ড JVM কভারেজ মেকানিজমের মাধ্যমে Jetpack Compose সমর্থন করে। তবে, Compose কোডে অনেক জেনারেটেড lambda এক্সপ্রেশন থাকে যা JaCoCo সম্পূর্ণরূপে কভার নাও করতে পারে। ফিল্টারের মাধ্যমে জেনারেটেড compose কোড রিপোর্ট থেকে বাদ দেওয়ার সুপারিশ করা হয়।
মিথ্যা কভারেজ ঘটে যখন একটি টেস্ট কোড এক্সিকিউট করে কিন্তু ফলাফল যাচাই করে না। সমাধান: প্রতিটি গুরুত্বপূর্ণ পরিস্থিতির জন্য assert চেক লেখা, টেস্টের গুণমান যাচাই করতে মিউটেশন টেস্টিং (Pitest) ব্যবহার করা, শুধুমাত্র শতাংশ নয় বরং কোন শাখাগুলি কভার হয়েছে তাও বিশ্লেষণ করা।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন