تشغيل الاختبارات في Go: كيفية تشغيل ملف معين فقط؟ دليل شامل

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

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

ابدأ الدورة

«هل يمكن تشغيل ملف واحد فقط مع الاختبارات؟» — نعم، وإليك كيفية القيام بذلك في Go

\n\n

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

\n\n

في هذه المقالة، سنحلل سؤالاً شائعاً من Stack Overflow (بالمناسبة، لديه آلاف المشاهدات): «How to run test cases in a specified file?». سنقوم بتكييف الإجابات مع واقع مطور Go ونعرض ليس فقط الأوامر الأساسية، ولكن أيضاً الحيل التي ستوفر لك ساعات من العمل. هيا بنا!

\n\n

لماذا لا يكون go test البسيط مناسباً دائماً؟

\n\n

في المشاريع الكبيرة، تنقسم الاختبارات إلى اختبارات وحدات، واختبارات تكامل، واختبارات شاملة. إذا قمت بتشغيل go test ./...، فإن Go يجتاز جميع الحزم الفرعية بشكل متكرر وينفذ جميع الاختبارات التي يجدها. قد يستغرق هذا دقائق. وإذا كان لديك اختبارات تصل إلى قاعدة بيانات أو واجهات برمجة تطبيقات خارجية، فقد تفشل لأسباب خارجة عن إرادتك. لذلك، فإن القدرة على تشغيل حالات الاختبار في ملف محدد ليست مجرد راحة، بل هي مهارة مطور محترف.

\n\n

الأمر الأساسي: go test مع اسم الملف

\n\n

الطريقة الأكثر مباشرة هي تحديد ملف معين مع الاختبارات. ولكن هناك فارق بسيط: Go يتطلب منك تحديد كل من الملف الذي يتم اختباره والملف الذي يحتوي على الاختبارات معاً. لماذا؟ لأن المترجم يجب أن يجمع كل شيفرة الحزمة.

\n\n

لنفترض أن لديك هيكل المشروع التالي:

\n\n
myproject/\n├── main.go\n└── math_utils.go\n└── math_utils_test.go\n
\n\n

لتشغيل الاختبارات فقط من math_utils_test.go، نفذ:

\n\n
go test -v math_utils.go math_utils_test.go\n
\n\n

العلم -v (verbose) سيعرض معلومات مفصلة عن كل حالة اختبار. بدونه، سترى النتيجة النهائية فقط: PASS أو FAIL.

\n\n

مثال على شيفرة حقيقية

\n\n

لننشئ ملفاً بسيطاً math_utils.go:

\n\n
package main\n\nfunc Sum(a, b int) int {\n    return a + b\n}\n\nfunc Multiply(a, b int) int {\n    return a * b\n}\n
\n\n

وملف الاختبار math_utils_test.go:

\n\n
package main\n\nimport "testing"\n\nfunc TestSum(t *testing.T) {\n    result := Sum(2, 3)\n    if result != 5 {\n        t.Errorf("Sum(2, 3) = %d; want 5", result)\n    }\n}\n\nfunc TestMultiply(t *testing.T) {\n    result := Multiply(3, 4)\n    if result != 12 {\n        t.Errorf("Multiply(3, 4) = %d; want 12", result)\n    }\n}\n
\n\n

الآن نشغل:

\n\n
$ go test -v math_utils.go math_utils_test.go\n=== RUN   TestSum\n--- PASS: TestSum (0.00s)\n=== RUN   TestMultiply\n--- PASS: TestMultiply (0.00s)\nPASS\nok      command-line-arguments  0.002s\n
\n\n

لاحظ المخرجات: ok command-line-arguments. هذا يعني أن Go قام بتجميع حزمة مؤقتة من الملفات المحددة. هذا الأسلوب يعمل، ولكن له قيود.

\n\n

مشكلة مع عدة ملفات في نفس الحزمة

\n\n

إذا كانت حزمتك تتكون من عدة ملفات (على سبيل المثال، math_utils.go و strings_utils.go)، وكان الاختبار في math_utils_test.go يستدعي دالة من strings_utils.go، فإن الأمر أعلاه سيفشل مع خطأ في التجميع. سيشتكي Go من أن الدالة غير معرفة.

\n\n

الحل هو سرد جميع الملفات التابعة. لكن هذا غير مريح. من الأفضل استخدام نهج آخر.

\n\n

الطريقة المتقدمة: تصفية الاختبارات حسب الاسم (-run)

\n\n

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

\n\n

مثال: تشغيل جميع الاختبارات التي تبدأ بـ TestSum:

\n\n
go test -v -run T                

المدونات

توصيات الكتب