Code Coverage در توسعه موبایل: چیست، معیارها و نحوه اندازه‌گیری

نویسنده: IT Sectr منتشر شده: 2026-04-09 زمان مطالعه: 9 دقیقه

Code Coverage (پوشش کد) معیاری است که نشان می‌دهد چه درصدی از کد منبع برنامه در طول آزمایش اجرا می‌شود. این معیار به تعیین کیفیت تست‌ها، شناسایی بخش‌های آزمایش‌نشده و اولویت‌بندی نوشتن تست‌های جدید کمک می‌کند. به گزارش Atlassian، 2025، سطح بهینه پوشش 70–80% است — بالاتر از این آستانه، هزینه‌های تست شروع به بیشتر شدن از منفعت می‌کند.

نکات کلیدی

  • Code Coverage — معیاری که درصد کد اجرا شده توسط تست‌ها را اندازه می‌گیرد
  • معیارهای پوشش شامل خطوط (line)، شاخه‌ها (branch)، توابع، شرایط و مسیرها
  • ابزارها: JaCoCo برای Android، XCCov برای iOS، SonarQube برای تحلیل کد
  • پوشش هدف 70–80% — تعادل بین کیفیت و هزینه تست‌ها
  • ادغام CI/CD امکان مسدود کردن ساخت‌ها در صورت کاهش پوشش زیر آستانه را فراهم می‌کند

Code Coverage چیست

Code Coverage (پوشش کد) یک معیار کمی است که تعیین می‌کند چه بخشی از کد منبع برنامه در طول اجرای تست‌ها اجرا شده است. این معیار به صورت درصد بیان می‌شود و به عنوان نسبت تعداد خطوط/شاخه‌های اجرا شده به تعداد کل محاسبه می‌شود. پوشش بالا عدم وجود باگ را تضمین نمی‌کند، اما خطر خطاهای نادیده گرفته شده را کاهش می‌دهد.

چرا پوشش را اندازه‌گیری کنیم

پوشش کد به تیم کمک می‌کند: بخش‌های آزمایش‌نشده کد را پیدا کند، در مورد اولویت‌های نوشتن تست تصمیم بگیرد، پویایی کیفیت تست را در CI/CD پیگیری کند. در توسعه موبایل، پوشش به ویژه برای منطق کسب‌وکار، مدل‌های داده و مخازن — لایه‌هایی که احتمال خطا در آنها بالاتر است — مهم است.

افسانه‌های Code Coverage

یک افسانه رایج: «100% پوشش = کیفیت ایده‌آل». در عمل، دستیابی به 100% پوشش بسیار نادر است و اغلب به قیمت تست‌های سطحی تمام می‌شود. پوشش مؤثر — مسابقه برای درصد نیست، بلکه پوشش استراتژیک مسیرهای بحرانی و شرایط مرزی است. پوشش چیزی در مورد کیفیت خود تست‌ها نمی‌گوید: یک تست ممکن است عبور کند، اما صحت نتیجه را بررسی نکند.

معیارهای پوشش کد

چندین معیار Code Coverage وجود دارد که هر کدام جنبه‌های مختلف تست را اندازه‌گیری می‌کنند. Line coverage (پوشش خطوط) — ساده‌ترین معیار است که درصد خطوط کد اجرا شده را نشان می‌دهد. Branch coverage (پوشش شاخه‌ها) اندازه‌گیری می‌کند که کدام شاخه‌های if-else و switch تست شده‌اند.

پوشش خطی (Line Coverage)

Line coverage هر خط از کد منبع را به عنوان اجرا شده یا نشده شمارش می‌کند. اگر در یک خط عملگر شرطی یا حلقه وجود داشته باشد، خط در صورت رسیدن کنترل به آن، حتی اگر همه شاخه‌ها پردازش نشده باشند، اجرا شده محسوب می‌شود. این کمترین معیار سختگیرانه است، اما قابل‌فهم‌ترین برای ارزیابی بصری است.

پوشش شاخه‌ها (Branch Coverage)

Branch coverage ارزیابی می‌کند که آیا تمام شاخه‌های ممکن در کد تست شده‌اند یا خیر. برای هر if-else هر دو شاخه در نظر گرفته می‌شود: true و false. برای switch — هر case. Branch coverage نسبت به line coverage معیار سختگیرانه‌تری محسوب می‌شود و بیشتر سناریوهای تست‌نشده را شناسایی می‌کند.

معیارچه چیزی را اندازه می‌گیردسختی دستیابی
Lineدرصد خطوط کد اجرا شدهکم
Branchدرصد شاخه‌های اجرا شده (if/else, switch)متوسط
Functionدرصد توابع و متدهای فراخوانی شدهکم
Conditionدرصد زیرعبارت‌های منطقی (&&, ||)زیاد

پوشش مسیر (Path Coverage)

Path coverage — سختگیرانه‌ترین معیار است که نیاز به بررسی تمام ترکیبات ممکن شاخه‌ها در یک تابع دارد. در عمل، path coverage به دلیل رشد نمایی تعداد ترکیبات به ندرت استفاده می‌شود: یک تابع با 10 شاخه دارای 1024 مسیر ممکن است.

ابزارهای اندازه‌گیری پوشش

در توسعه موبایل بسته به پلتفرم از ابزارهای مختلفی برای اندازه‌گیری Code Coverage استفاده می‌شود. برای Android استاندارد JaCoCo (Java Code Coverage) است که با Gradle ادغام می‌شود و هم تست‌های واحد و هم تست‌های ابزاری را پشتیبانی می‌کند. برای iOS از XCCov تعبیه شده در Xcode استفاده می‌شود.

JaCoCo برای Android

JaCoCo گزارش‌هایی در قالب‌های HTML، XML و CSV تولید می‌کند. گزارش HTML خطوط را به صورت بصری برجسته می‌کند: سبز — اجرا شده، قرمز — رد شده، زرد — تا حدی اجرا شده. گزارش XML با SonarQube و سایر سیستم‌های تحلیل کد سازگار است. JaCoCo از فیلتر کردن کلاس‌ها پشتیبانی می‌کند: می‌توان کد تولید شده، databinding، BuildConfig را حذف کرد.

groovy
// build.gradle — راه‌اندازی JaCoCo
android {
    buildTypes {
        debug {
            testCoverageEnabled = true
        }
    }
}

// ایجاد گزارش JaCoCo
task jacocoTestReport(type: JacocoReport) {
    dependsOn 'testDebugUnitTest'
    reports {
        xml.enabled = true
        html.enabled = true
    }
}

XCCov برای iOS

XCCov — ابزار داخلی Xcode برای اندازه‌گیری پوشش کد. از طریق Gather coverage data در طرح تست فعال می‌شود. XCCov از پوشش برای Swift و Objective-C پشتیبانی می‌کند، گزارش‌هایی در قالب .xccovreport تولید می‌کند و با CI از طریق xcodebuild -enableCodeCoverage YES ادغام می‌شود. داده‌ها در کنسول نمایش داده می‌شوند و می‌توانند به JSON صادر شوند.

SonarQube و Codecov

برای نظارت متمرکز پوشش از پلتفرم‌هایی استفاده می‌شود: SonarQube (تحلیل کیفیت کد + پوشش)، Codecov و Coveralls. این سرویس‌ها داده‌ها را از JaCoCo و XCCov جمع‌آوری می‌کنند، روندها، Quality Gate و ادغام با GitHub/GitLab را از طریق نظرات PR نشان می‌دهند.

چگونه پوشش کد را بهبود دهیم

افزایش Code Coverage نیاز به یک رویکرد سیستماتیک دارد: نه «رسیدن به درصد»، بلکه پوشش ریسک‌ها. اولین قدم تحلیل گزارش JaCoCo یا XCCov است — شناسایی کلاس‌های قرمز (پوشش‌نشده). اولویت: منطق کسب‌وکار → مخازن → ViewModel → کامپوننت‌های UI.

استراتژی TDD

Test-Driven Development (TDD) به طور خودکار پوشش بالایی را تضمین می‌کند، زیرا تست‌ها قبل از پیاده‌سازی نوشته می‌شوند. فرآیند: قرمز (نوشتن تست ناموفق) → سبز (نوشتن حداقل کد) → بازسازی. TDD برنامه‌نویس را منضبط می‌کند و او را مجبور به پوشش موارد مرزی و شرایط استثنایی می‌کند که اغلب بدون تست باقی می‌مانند.

تست‌های پارامتری

یک تست پارامتری جایگزین ده‌ها تست معمولی می‌شود. JUnit و XCTest از پارامتری پشتیبانی می‌کنند: @ParameterizedTest در JUnit 5، XCTestCase با testPerformanceExample در XCTest. پارامتری امکان بررسی داده‌های ورودی متعدد را بدون تکرار کد فراهم می‌کند که به طور قابل توجهی پوشش شاخه‌ها و شرایط را گسترش می‌دهد.

kotlin
// تست پارامتری شده در 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

رایج‌ترین اشتباه — دویدن به دنبال درصد بدون تحلیل کیفیت تست‌ها. تیم شروع به نوشتن تست برای تست می‌کند: getter و setter را بررسی می‌کند، پوشش را در سطوح مختلف تکراری می‌کند، متدهای پیش پا افتاده را تست می‌کند. این درصد بالایی می‌دهد اما کیفیت واقعی را افزایش نمی‌دهد.

احساس امنیت کاذب

Code Coverage بالا می‌تواند این تصور غلط را ایجاد کند که برنامه به خوبی تست شده است. یک تست ممکن است خط کد را اجرا کند، اما صحت نتیجه را بررسی نکند. به عنوان مثال: تست متد محاسبه تخفیف را فراخوانی می‌کند، اما مبلغ را بررسی نمی‌کند — خط اجرا شده، پوشش افزایش می‌یابد، اما باگ پیدا نشده است.

نادیده گرفتن موارد مرزی

اشتباه معمول — تست فقط «مسیر خوشحال» (happy path) و نادیده گرفتن موارد مرزی: لیست‌های خالی، مقادیر null، اعداد حداکثر، فرمت‌های نامعتبر. بیشتر باگ‌ها دقیقاً در مرزها و استثناها رخ می‌دهند. Branch coverage به شناسایی شاخه‌های از دست رفته کمک می‌کند، اما بررسی مقادیر مرزی را تضمین نمی‌کند.

Mutation Testing — بررسی کیفیت تست‌ها

Mutation Testing روشی برای ارزیابی کیفیت تست‌ها است که در آن جهش‌هایی (خطاهای مصنوعی) به کد منبع وارد می‌شود و بررسی می‌شود که آیا تست‌ها شکست می‌خورند یا خیر. Pitest — ابزار محبوب mutation testing برای Java و Kotlin. اگر تست‌ها در جهش شکست نخورند — به این معنی است که آن شرط را بررسی نمی‌کنند.

اصل کار Pitest

Pitest جهش‌یافته‌هایی ایجاد می‌کند — نسخه‌های تغییر یافته کد منبع، که در آنها مثلاً > با >=، true با false جایگزین شده یا فراخوانی متد حذف شده است. سپس برای هر جهش‌یافته تست‌ها اجرا می‌شوند. اگر تست‌ها عبور کنند — جهش‌یافته زنده ماند، یعنی تست‌ها این سناریو را پوشش نمی‌دهند. اگر تست‌ها شکست بخورند — جهش‌یافته کشته شد، تست صحیح است.

groovy
// 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--). هرچه تعداد بیشتری از انواع جهش توسط تست‌ها کشته شوند، مجموعه تست قابل اعتمادتر است.

هدف Mutation Score

نمره جهش هدف — 80% و بالاتر. این بدان معناست که 80% خطاهای مصنوعی توسط تست‌ها شناسایی شده‌اند. پوشش کد (Code Coverage) 90% تضمین نمی‌کند که تست‌ها خطاها را پیدا می‌کنند — mutation testing ارزیابی عینی‌تری ارائه می‌دهد. Pitest می‌تواند به عنوان Quality Gate در CI ادغام شود و در صورت کاهش نمره جهش زیر آستانه، ساخت را مسدود کند.

ادغام Code Coverage در CI/CD

برای کنترل خودکار Code Coverage در CI/CD از Quality Gates — مقادیر آستانه‌ای استفاده می‌شود که در صورت نقض، ساخت به عنوان ناپایدار علامت‌گذاری یا رد می‌شود. SonarQube امکان پیکربندی Quality Gate را بر اساس ترکیبی از معیارها فراهم می‌کند: پوشش (≥80%)، تعداد باگ‌ها، آسیب‌پذیری‌ها و کد تکراری.

پیکربندی Quality Gate در GitHub Actions

در GitHub Actions، Code Coverage از طریق مراحل action ادغام می‌شود: اجرای تست‌ها با پوشش → بارگذاری گزارش در Codecov → بررسی آستانه. Codecov به طور خودکار PR را با diff پوشش نظر می‌دهد و نشان می‌دهد کدام خطوط تغییر کرده‌اند و چگونه بر درصد کلی تأثیر گذاشته‌اند. اگر پوشش کاهش یافته باشد — PR تا نوشتن تست‌های اضافی مسدود می‌شود.

yaml
# 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

گزارش‌دهی و تجسم

گزارش‌های HTML JaCoCo و XCCov شامل برجسته‌سازی بصری پوشش هستند: سبز — خطوط اجرا شده، قرمز — اجرا نشده. SonarQube علاوه بر این پوشش را در سطح فایل، کلاس، متد و خط و همچنین تاریخچه تغییرات پوشش در اسپرینت‌ها نشان می‌دهد. این به تصمیم‌گیری در مورد بازسازی و افزودن تست‌ها کمک می‌کند.

سوالات متداول

چند درصد Code Coverage خوب محسوب می‌شود؟

برای پروژه‌های موبایل، پوشش 70–80% برای منطق کسب‌وکار و 50–60% برای کامپوننت‌های UI خوب محسوب می‌شود. بالای 80% هزینه‌های تست شروع به بیشتر شدن از منفعت می‌کند. مهم است به خاطر داشته باشیم که درصد هدف نیست، بلکه شاخص است و ماژول‌های مختلف ممکن است سطوح هدف متفاوتی داشته باشند.

تفاوت بین Line و Branch Coverage چیست؟

Line Coverage نشان می‌دهد که چند خط کد اجرا شده است. Branch Coverage — چند شاخه (if-else, switch) تست شده است. یک خط با if ممکن است اجرا شود، اما شاخه true تست شده و false — نه. Branch Coverage سختگیرانه‌تر است و سناریوهای از دست رفته بیشتری را شناسایی می‌کند.

چگونه Code Coverage را در CI/CD ادغام کنیم؟

در CI/CD پوشش از طریق Quality Gate ادغام می‌شود: اگر پوشش زیر آستانه باشد، ساخت مسدود می‌شود. برای Android از JaCoCo + SonarQube، برای iOS — xcodebuild -enableCodeCoverage با تجزیه .xccovreport استفاده می‌شود. GitHub Actions actionهای آماده برای Codecov دارد.

آیا می‌توان پوشش را برای Jetpack Compose اندازه‌گیری کرد؟

بله، JaCoCo از Jetpack Compose از طریق مکانیزم استاندارد پوشش JVM پشتیبانی می‌کند. با این حال، کد Compose حاوی عبارات lambda تولید شده زیادی است که JaCoCo ممکن است به طور کامل پوشش ندهد. توصیه می‌شود کد compose تولید شده را از طریق فیلترها از گزارش حذف کنید.

چگونه از پوشش کاذب جلوگیری کنیم؟

پوشش کاذب زمانی رخ می‌دهد که تست کد را اجرا می‌کند اما نتیجه را بررسی نمی‌کند. راه‌حل: نوشتن بررسی‌های assert برای هر سناریوی مهم، استفاده از mutation testing (Pitest) برای بررسی کیفیت تست‌ها، تحلیل نه تنها درصد بلکه اینکه کدام شاخه‌ها پوشش داده شده‌اند.

خلاصه

  • Code Coverage — معیاری که درصد کد اجرا شده توسط تست‌ها را نشان می‌دهد، اما عدم وجود باگ را تضمین نمی‌کند
  • Line و Branch coverage — معیارهای اصلی؛ Branch سختگیرانه‌تر است و شاخه‌های تست‌نشده را شناسایی می‌کند
  • JaCoCo — ابزار استاندارد برای Android، XCCov — برای iOS، هر دو با Gradle و Xcode ادغام می‌شوند
  • پوشش هدف 70–80% برای منطق کسب‌وکار — تعادل بهینه بین کیفیت و هزینه
  • TDD و پارامتری — روش‌های مؤثر افزایش پوشش بدون تکرار تست‌ها
  • SonarQube و Codecov — پلتفرم‌هایی برای نظارت متمرکز و Quality Gate در CI/CD
  • قانون اصلی: به دنبال درصد ندویم، بلکه ریسک‌های بحرانی و موارد مرزی را پوشش دهیم

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید