تغطية الكود بالاختبارات في Rust: من الصفر إلى الثقة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

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

\n\n

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

\n\n

ولكن لنكن صادقين: السعي وراء تغطية 100% هو فخ. الأهم هو فهم أي الأسطر بقيت بدون اختبارات ولماذا. في هذه المقالة، سنستعرض ثلاث أدوات رئيسية لـ Rust: tarpaulin وgrcov والأدوات المدمجة في LLVM. ستتعلم كيفية تحويل النسب المئوية الجافة إلى رؤى قابلة للتنفيذ لإعادة الهيكلة.

\n\n

لماذا يجب على مطور Rust متابعة التغطية؟

\n

تشتهر Rust بأمان الذاكرة، لكن هذا لا يلغي الأخطاء المنطقية. تساعد تغطية الكود بالاختبارات في:

\n
    \n
  • اكتشاف "الكود الميت" — الدوال أو الفروع التي لا يتم استدعاؤها أبدًا.
  • \n
  • زيادة الثقة عند إعادة الهيكلة — بمعرفة أن المسارات الحرجة مغطاة بالاختبارات.
  • \n
  • تحسين التوثيق — غالبًا ما تكون الاختبارات أفضل توثيق إذا كانت تغطي جميع السيناريوهات.
  • \n
\n

المقياس الرئيسي هو line coverage (تغطية الأسطر)، لكننا سننظر أيضًا إلى branch coverage (تغطية الفروع)، وهو مهم بشكل خاص في Rust بسبب كثرة تعبيرات match.

\n\n

الأداة رقم 1: cargo-tarpaulin — البساطة والسرعة

\n

tarpaulin هي الأداة الأكثر شيوعًا لتغطية الكود في Rust. تعمل "فورًا" ولا تتطلب إعدادًا معقدًا. التثبيت:

\n
cargo install cargo-tarpaulin
\n

تشغيل التحليل الأساسي:

\n
cargo tarpaulin --out Html
\n

سينشئ هذا الأمر تقرير HTML في مجلد tarpaulin-report.html. افتحه — وسترى خريطة ألوان لمشروعك: أسطر خضراء (مغطاة بالاختبارات)، حمراء (غير مغطاة)، ورمادية (غير عاملة، مثل التعليقات).

\n\n

مثال: اختبار دالة بسيطة

\n

لننشئ ملف src/lib.rs بدالة حساب المضروب:

\n
pub fn factorial(n: u32) -> u32 {\n    match n {\n        0 | 1 => 1,\n        _ => n * factorial(n - 1),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_factorial() {\n        assert_eq!(factorial(0), 1);\n        assert_eq!(factorial(1), 1);\n        assert_eq!(factorial(5), 120);\n    }\n}
\n

شغل tarpaulin:

\n
cargo tarpaulin --ignore-tests --out Html
\n

العلم --ignore-tests يستبعد كود الاختبارات نفسه من التقرير. النتيجة: تغطية 100% لهذه الدالة. لكن دعنا نعقد المهمة — نضيف معالجة الأخطاء:

\n
pub fn factorial_safe(n: i32) -> Result<u32, String> {\n    if n < 0 {\n        return Err("رقم سالب!".to_string());\n    }\n    Ok(factorial(n as u32))\n}
\n

الآن سيظهر tarpaulin أن الفرع Err غير مغطى بالاختبارات. أضف اختبارًا:

\n
#[test]\nfn test_negative() {\n    assert!(factorial_safe(-5).is_err());\n}
\n

بعد التشغيل مرة أخرى، ستصبح التغطية 100% مرة أخرى.

\n\n

إعدادات متقدمة لـ tarpaulin

\n

للمشاريع الكبيرة، استخدم:

\n
    \n
  • --fail-under 80 — خروج مع خطأ إذا كانت التغطية أقل من 80%.
  • \n
  • --skip-clean — لا تعيد بناء المشروع إذا كانت التغييرات طفيفة.
  • \n
  • --engine llvm — استخدم أدوات LLVM (تجريبي، لكنه أكثر دقة).
  • \n
\n\n

الأداة رقم 2: grcov — ملك التكاملات

\n

grcov هي أداة أكثر مرونة تعمل مع أدوات LLVM. وهي مفيدة بشكل خاص إذا كنت تستخدم CI/CD (GitHub Actions, GitLab

المدونات

توصيات الكتب