تغطية الاختبارات في Go: قياس وتحسين جودة الكود

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

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

ابدأ الدورة

كيفية قياس تغطية الاختبارات في Go دون أن تصاب بالجنون

\n\n

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

\n\n

سؤال "How to measure test coverage in Go" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow (عشرات الآلاف من المشاهدات). وهذا ليس من قبيل الصدفة. المطورون لا يريدون فقط كتابة الاختبارات، بل فهم مدى فعاليتها. في هذا الدليل التعليمي، سنشرح جميع طرق قياس تغطية الاختبارات في Go: من الأوامر الأساسية إلى التقنيات المتقدمة مع ملفات التعريف وتقارير HTML.

\n\n

ما هي تغطية الاختبارات ولماذا يجب قياسها؟

\n\n

Test coverage (تغطية الكود بالاختبارات) هي مقياس يوضح النسبة المئوية من الكود المصدري الخاص بك التي يتم تنفيذها أثناء الاختبارات. يتم التعبير عنها كنسبة مئوية. 100% coverage ليست دائمًا الكأس المقدسة، ولكن السعي لتحقيق نسب عالية يستحق العناء.

\n\n

لماذا هذا ضروري؟

\n
    \n
  • مراقبة الجودة: ترى أي أجزاء من الكود بقيت بدون اختبارات
  • \n
  • الثقة في إعادة الهيكلة: التغطية العالية تقلل من خطر كسر شيء ما
  • \n
  • مقاييس CI/CD: يمكنك تعيين حد للتغطية ومنع الكود ذي التغطية المنخفضة
  • \n
  • التوثيق: الاختبارات هي توثيق حي، والتغطية تظهر مدى اكتمالها
  • \n
\n\n

المفاجأة: التغطية ≠ جودة الاختبارات

\n

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

\n\n

القياس الأساسي: go test -cover

\n\n

لنبدأ بالأبسط. Go لديه دعم مدمج للتغطية مباشرة في أداة go test. دعنا ننشئ مشروعًا بسيطًا ونرى كيف يعمل هذا.

\n\n

أنشئ ملفًا باسم math.go:

\n\n
package main\n\nfunc Add(a, b int) int {\n    return a + b\n}\n\nfunc Subtract(a, b int) int {\n    return a - b\n}\n\nfunc Multiply(a, b int) int {\n    return a * b\n}\n\nfunc Divide(a, b int) (int, error) {\n    if b == 0 {\n        return 0, nil // خطأ: يجب أن يكون return 0, errors.New("division by zero")\n    }\n    return a / b, nil\n}
\n\n

والآن — الاختبار (math_test.go):

\n\n
package main\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n    result := Add(2, 3)\n    if result != 5 {\n        t.Errorf("expected 5, got %d", result)\n    }\n}\n\nfunc TestSubtract(t *testing.T) {\n    result := Subtract(10, 4)\n    if result != 6 {\n        t.Errorf("expected 6, got %d", result)\n    }\n}\n\n// لا نختبر Multiply و Divide عمدًا
\n\n

الآن شغّل الاختبارات مع العلم -cover:

\n\n
go test -cover
\n\n

سيكون الإخراج مشابهًا لهذا:

\n\n
ok      example/math    0.002s  coverage: 50.0% of statements
\n\n

هذا صحيح — تمت تغطية 50% من الكود، لأن Multiply و Divide لا يتم اختبارهما. لكن هذا مجرد رقم إجمالي. ماذا لو أردنا رؤية ملف تعريف تغطية مفصل؟

\n\n

ملف تعريف التغطية: go test -coverprofile

\n\n

العلم -coverprofile يحفظ معلومات مفصلة عن التغطية في ملف:

\n\n
go test -coverprofile=coverage.out
\n\n

الآن ظهر ملف باسم coverage.out في المجلد. افتحه — إنه تنسيق نصي، حيث يظهر كل سطر ما إذا تم تنفيذ تعليمة معينة من الكود أم لا. لكن قراءته يدويًا مملة. دعنا ننتقل إلى التصور.

\n\n

تقرير HTML: go tool cover -html

\n\n

الطريقة الأكثر ملاءمة لتحليل التغطية هي تقرير HTML. يبرز الكود المنفذ باللون الأخضر، والكود غير المنفذ باللون الأحمر.

\n\n
go tool cove                

المدونات

توصيات الكتب