تغطية الكود في تطوير التطبيقات المحمولة: ما هي، المقاييس وكيفية القياس

المؤلف: IT Sectr نُشر: 2026-04-09 وقت القراءة: 9 دق

تغطية الكود (Code Coverage) هي مقياس يوضح النسبة المئوية للكود المصدري للتطبيق التي يتم تنفيذها أثناء الاختبار. تساعد في تحديد جودة الاختبارات، اكتشاف الأجزاء غير المختبرة، وتحديد أولويات كتابة اختبارات جديدة. وفقًا لـ Atlassian، 2025، فإن المستوى الأمثل للتغطية هو 70–80% — فوق هذه العتبة، تبدأ تكاليف الاختبار في تجاوز الفوائد.

الخلاصة

  • تغطية الكود — مقياس يقيس النسبة المئوية للكود المنفذ بواسطة الاختبارات
  • مقاييس التغطية تشمل السطور (line)، الفروع (branch)، الدوال، الشروط والمسارات
  • الأدوات: JaCoCo لنظام Android، XCCov لنظام iOS، SonarQube لتحليل الكود
  • التغطية المستهدفة 70–80% — توازن بين الجودة وتكلفة الاختبارات
  • التكامل مع CI/CD يسمح بحظر البناء عند انخفاض التغطية تحت العتبة

ما هي تغطية الكود

تغطية الكود (Code Coverage) هي مقياس كمي يحدد أي جزء من الكود المصدري للتطبيق تم تنفيذه أثناء الاختبارات. يتم التعبير عنها كنسبة مئوية وتحسب كنسبة السطور/الفروع المنفذة إلى الإجمالي. التغطية العالية لا تضمن عدم وجود أخطاء، ولكنها تقلل من خطر الأخطاء غير المكتشفة.

لماذا نقيس التغطية

تساعد تغطية الكود الفريق في: اكتشاف الأجزاء غير المختبرة من الكود، اتخاذ القرارات حول أولويات كتابة الاختبارات، تتبع ديناميكيات جودة الاختبار في CI/CD. في تطوير التطبيقات المحمولة، التغطية مهمة بشكل خاص لمنطق الأعمال، نماذج البيانات والمستودعات — الطبقات التي يكون فيها احتمال الأخطاء أعلى.

خرافات حول تغطية الكود

خرافة شائعة: «تغطية 100% = جودة مثالية». في الممارسة العملية، تغطية 100% نادرة للغاية وغالبًا ما تكون على حساب اختبارات سطحية. التغطية الفعالة ليست سباقًا نحو النسبة المئوية، بل تغطية استراتيجية للمسارات الحرجة والحالات الحدودية. التغطية لا تخبرنا شيئًا عن جودة الاختبارات نفسها: قد ينجح الاختبار لكنه لا يتحقق من صحة النتيجة.

مقاييس تغطية الكود

توجد عدة مقاييس لتغطية الكود، كل منها يقيس جوانب مختلفة من الاختبار. تغطية السطور (Line coverage) هي أبسط مقياس، يوضح النسبة المئوية لسطور الكود المنفذة. تغطية الفروع (Branch coverage) تقيس أي تقسيمات if-else و switch تم اختبارها.

تغطية السطور (Line Coverage)

تغطية السطور تحسب كل سطر من الكود المصدري كمنفذ أو غير منفذ. إذا كان السطر يحتوي على عامل شرطي أو حلقة، يعتبر السطر منفذًا إذا وصل التحكم إليه، حتى لو لم تتم معالجة جميع الفروع. هذا هو المقياس الأقل صرامة، لكنه الأكثر فهماً للتقييم البصري.

تغطية الفروع (Branch Coverage)

تغطية الفروع تقيم ما إذا كانت جميع التفرعات الممكنة في الكود قد تم اختبارها. لكل if-else يتم أخذ كلا الفرعين في الاعتبار: true و false. بالنسبة لـ switch، يتم أخذ كل case. تغطية الفروع تعتبر مقياسًا أكثر صرامة من تغطية السطور وتكشف غالبًا عن سيناريوهات غير مختبرة.

المقياسما يقيسهصعوبة التحقيق
Lineنسبة سطور الكود المنفذةمنخفضة
Branchنسبة الفروع المنفذة (if/else, switch)متوسطة
Functionنسبة الدوال والطرق المستدعاةمنخفضة
Conditionنسبة التعبيرات الفرعية المنطقية (&&, ||)عالية

تغطية المسارات (Path Coverage)

تغطية المسارات هي المقياس الأكثر صرامة، وتتطلب التحقق من جميع التوليفات الممكنة للتفرعات في الدالة. في الممارسة العملية، نادرًا ما تستخدم تغطية المسارات بسبب النمو الأسي لعدد التوليفات: دالة بها 10 تفرعات لديها 1024 مسارًا ممكنًا.

أدوات قياس التغطية

في تطوير التطبيقات المحمولة، تُستخدم أدوات مختلفة لقياس تغطية الكود حسب المنصة. لنظام Android، المعيار هو JaCoCo (Java Code Coverage)، الذي يتكامل مع Gradle ويدعم كلاً من اختبارات الوحدة واختبارات الأجهزة. لنظام iOS، يُستخدم XCCov المدمج في Xcode.

JaCoCo لنظام Android

JaCoCo ينشئ تقارير بتنسيقات HTML و XML و CSV. تقرير HTML يبرز السطور بصريًا: أخضر — منفذة، أحمر — مفقودة، أصفر — منفذة جزئيًا. تقرير XML متوافق مع SonarQube وأنظمة تحليل الكود الأخرى. JaCoCo يدعم تصفية الفئات: يمكن استبعاد الكود المُنشأ، ربط البيانات و 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.

كيفية تحسين تغطية الكود

تحسين تغطية الكود يتطلب نهجًا منهجيًا: ليس «رفع النسب المئوية»، بل تغطية المخاطر. الخطوة الأولى هي تحليل تقرير JaCoCo أو XCCov — تحديد الفئات الحمراء (غير المغطاة). الأولوية: منطق الأعمال → المستودعات → ViewModel → مكونات واجهة المستخدم.

استراتيجية TDD

التطوير القائم على الاختبار (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)
}

أخطاء عند العمل مع تغطية الكود

الخطأ الأكثر شيوعًا هو السعي وراء النسبة المئوية دون تحليل جودة الاختبارات. يبدأ الفريق في كتابة اختبارات من أجل الاختبارات: التحقق من getters و setters، تكرار التغطية على مستويات مختلفة، اختبار طرق تافهة. هذا يعطي نسبة مئوية عالية لكنه لا يحسن الجودة الحقيقية.

شعور زائف بالأمان

تغطية عالية للكود يمكن أن تخلق شعورًا زائفًا بأن التطبيق مختبر جيدًا. قد ينفذ الاختبار سطرًا من الكود لكنه لا يتحقق من صحة النتيجة. على سبيل المثال: اختبار يستدعي طريقة حساب الخصم لكنه لا يتحقق من المبلغ — السطر منفذ، التغطية تزيد، لكن الخطأ لا يُكتشف.

تجاهل الحالات الحدودية

خطأ نموذجي هو اختبار «المسار السعيد» (happy path) فقط وتجاهل الحالات الحدودية: القوائم الفارغة، قيم null، الأرقام القصوى، التنسيقات غير الصحيحة. على الحدود والاستثناءات تحدث معظم الأخطاء. تغطية الفروع تساعد في اكتشاف الفروع المفقودة، لكنها لا تضمن التحقق من القيم الحدودية.

اختبار التحول — التحقق من جودة الاختبارات

اختبار التحول (Mutation Testing) هو طريقة لتقييم جودة الاختبارات حيث يتم إدخال تحولات (أخطاء اصطناعية) في الكود المصدري والتحقق مما إذا كانت الاختبارات تفشل. Pitest هي أداة شائعة لاختبار التحول في 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--). كلما زادت أنواع التحولات التي تقتلها الاختبارات، كانت مجموعة الاختبارات أكثر موثوقية.

هدف درجة التحول

درجة التحول المستهدفة هي 80% أو أعلى. هذا يعني أن 80% من الأخطاء الاصطناعية يتم اكتشافها بواسطة الاختبارات. تغطية الكود بنسبة 90% لا تضمن أن الاختبارات تجد الأخطاء — اختبار التحول يوفر تقييمًا أكثر موضوعية. Pitest يمكن دمجه في CI كبوابة جودة، مما يمنع البناء عند انخفاض درجة التحول تحت العتبة.

دمج تغطية الكود في CI/CD

للتحكم التلقائي في تغطية الكود في CI/CD، تُستخدم بوابات الجودة (Quality Gates) — قيم عتبة، عند انتهاكها، يتم وضع علامة على البناء كغير مستقر أو رفضه. SonarQube يسمح بتكوين بوابة الجودة بناءً على مجموعة من المقاييس: التغطية (≥80%)، عدد الأخطاء، الثغرات الأمنية والكود المكرر.

إعداد بوابة الجودة في GitHub Actions

في GitHub Actions، يتم دمج تغطية الكود من خلال خطوات الإجراء: تشغيل الاختبارات مع التغطية → تحميل التقرير إلى Codecov → التحقق من العتبة. Codecov يعلق تلقائيًا على PR مع فرق التغطية، موضحًا أي السطور تغيرت وكيف أثر ذلك على النسبة المئوية الإجمالية. إذا انخفضت التغطية، يتم حظر 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 بالإضافة إلى ذلك يُظهر التغطية على مستوى الملف، الفئة، الطريقة والسطر، بالإضافة إلى تاريخ تغيير التغطية عبر السباقات. هذا يساعد في اتخاذ قرارات حول إعادة الهيكلة وإضافة الاختبارات.

الأسئلة الشائعة

ما هي نسبة تغطية الكود التي تعتبر جيدة؟

للمشاريع المحمولة، تعتبر التغطية 70–80% لمنطق الأعمال و 50–60% لمكونات واجهة المستخدم جيدة. فوق 80%، تبدأ تكاليف الاختبار في تجاوز الفوائد. من المهم تذكر أن النسبة المئوية ليست هدفًا بل مؤشر، وقد يكون للوحدات المختلفة مستويات مستهدفة مختلفة.

ما الفرق بين تغطية السطور وتغطية الفروع؟

تغطية السطور توضح عدد سطور الكود التي تم تنفيذها. تغطية الفروع توضح عدد التفرعات (if-else, switch) التي تم اختبارها. قد يتم تنفيذ سطر يحتوي على if، ولكن قد يتم اختبار الفرع true فقط وليس false. تغطية الفروع أكثر صرامة وتكشف المزيد من السيناريوهات المفقودة.

كيفية دمج تغطية الكود في CI/CD؟

في CI/CD، يتم دمج التغطية عبر بوابة الجودة (Quality Gate): يتم حظر البناء إذا كانت التغطية أقل من العتبة. لنظام Android، يُستخدم JaCoCo + SonarQube، لنظام iOS — xcodebuild -enableCodeCoverage مع تحليل .xccovreport. GitHub Actions يحتوي على إجراءات جاهزة لـ Codecov.

هل يمكن قياس التغطية لـ Jetpack Compose؟

نعم، JaCoCo يدعم Jetpack Compose عبر آلية تغطية JVM القياسية. ومع ذلك، يحتوي كود Compose على العديد من تعبيرات lambda المُنشأة التي قد لا يغطيها JaCoCo بالكامل. يُوصى باستبعاد كود Compose المُنشأ من التقرير عبر المرشحات.

كيفية تجنب التغطية الزائفة؟

تحدث التغطية الزائفة عندما ينفذ الاختبار كودًا لكنه لا يتحقق من النتيجة. الحل: كتابة تأكيدات (assert) لكل سيناريو مهم، استخدام اختبار التحول (Pitest) للتحقق من جودة الاختبارات، تحليل ليس فقط النسبة المئوية ولكن أيضًا أي الفروع مغطاة.

الخلاصة

  • تغطية الكود — مقياس يوضح النسبة المئوية للكود المنفذ بواسطة الاختبارات، لكنه لا يضمن عدم وجود أخطاء
  • تغطية السطور والفروع — المقاييس الرئيسية؛ تغطية الفروع أكثر صرامة وتكشف الفروع غير المختبرة
  • JaCoCo — الأداة القياسية لنظام Android، XCCov — لنظام iOS، كلاهما يتكامل مع Gradle و Xcode
  • التغطية المستهدفة 70–80% لمنطق الأعمال — توازن مثالي بين الجودة والتكلفة
  • TDD والتوسيم — طرق فعالة لزيادة التغطية دون تكرار الاختبارات
  • SonarQube و Codecov — منصات للمراقبة المركزية وبوابات الجودة في CI/CD
  • القاعدة الرئيسية: لا تسعَ وراء النسبة المئوية، بل قم بتغطية المخاطر الحرجة والحالات الحدودية

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا