تحية للجميع! يتبقى أقل من أسبوع قبل بدء دورة
"Golang Developer" ونواصل تبادل المواد المفيدة حول الموضوع. دعنا نذهب!

يحتوي Go على مكتبة مضمنة جيدة وموثوقة للاختبار. إذا كتبت على Go ، فأنت تعلم ذلك بالفعل. في هذه المقالة ، سنتحدث عن العديد من الاستراتيجيات التي يمكن أن تحسن مهاراتك في الاختبار باستخدام Go. من تجربة كتابة قاعدة الكود الرائعة على Go ، تعلمنا أن هذه الاستراتيجيات تعمل حقًا وبالتالي تساعد في توفير الوقت والجهد في العمل مع الكود.
استخدام أجنحة الاختبارإذا كنت تتعلم بنفسك شيئًا مفيدًا واحدًا فقط من هذه المقالة ، فيجب أن يكون استخدام مجموعات الاختبار. بالنسبة لأولئك الذين ليسوا على دراية بهذا المفهوم ، فإن الاختبار بواسطة مجموعات هو عملية تطوير اختبار لاختبار واجهة مشتركة يمكن استخدامها في العديد من تطبيقات هذه الواجهة. يمكنك أدناه معرفة كيفية اجتياز العديد من تطبيقات
Thinger
المختلفة وتشغيلها بنفس الاختبارات.
type Thinger interface { DoThing(input string) (Result, error) }
لقد عمل القراء المحظوظون على قواعد الكود التي تستخدم هذه الطريقة. غالبًا ما يتم استخدامه في اختبارات الأنظمة المستندة إلى المكونات الإضافية والتي تتم كتابتها لاختبار واجهة ، من قبل جميع تطبيقات هذه الواجهة لفهم كيفية استيفائها لمتطلبات السلوك.
من المحتمل أن يساعد استخدام هذا النهج في توفير ساعات وأيام وحتى وقت كاف لحل مشكلة المساواة بين
الفئتين P و NP . أيضًا ، عند استبدال نظام أساسي مع نظام آخر ، تختفي الحاجة إلى كتابة (عدد كبير) من الاختبارات الإضافية ، وهناك أيضًا ثقة في أن هذا النهج لن يؤدي إلى تعطيل تشغيل التطبيق الخاص بك. ضمنيا ، تحتاج إلى إنشاء واجهة تحدد مساحة المنطقة التي تم اختبارها. باستخدام حقن التبعية ، يمكنك تخصيص مجموعة من الحزمة التي يتم تمريرها في تنفيذ الحزمة بأكملها.
يمكنك العثور على مثال كامل
هنا . على الرغم من أن هذا المثال بعيد المنال ، يمكن للمرء أن يتخيل أن قاعدة بيانات واحدة بعيدة والآخر في الذاكرة.
يوجد مثال رائع آخر لهذه التقنية في المكتبة القياسية في الحزمة
golang.org/x/net/nettest
. يوفر وسيلة للتحقق من أن net.Conn يرضي الواجهة.
تجنب تلوث الواجهةلا يمكنك التحدث عن الاختبار في Go ، ولكن لا تتحدث عن الواجهات.
تعتبر الواجهات مهمة في سياق الاختبار ، لأنها الأداة الأقوى في ترسانة الاختبار لدينا ، لذلك تحتاج إلى استخدامها بشكل صحيح.
غالبًا ما تقوم الحزم بتصدير واجهات للمطورين ، وهذا يؤدي إلى حقيقة:
أ) المطورين خلق وهمية الخاصة بهم لتنفيذ الحزمة ؛
ب) الحزمة تصدير وهمية الخاصة بها.
"كلما كبرت الواجهة ، أضعف التجريد"
- روب بايك ، اقوال العودة
يجب فحص الواجهات بعناية قبل التصدير. غالبًا ما يكون من المغري تصدير الواجهات لمنح المستخدمين القدرة على محاكاة السلوك الذي يحتاجونه. بدلاً من ذلك ، قم بتوثيق الواجهات التي تتلاءم مع بنياتك حتى لا تنشئ علاقة وثيقة بين حزمة المستهلك وتلك الخاصة. مثال رائع على ذلك هو حزمة
الأخطاء .
عندما يكون لدينا واجهة لا نريد تصديرها ، يمكننا استخدام
الشجرة الفرعية الداخلية / الحزمة لحفظها داخل الحزمة. وبالتالي ، لا يمكننا أن نخاف من أن المستخدم النهائي قد يعتمد عليه ، وبالتالي ، قد يكون مرنًا في تغيير الواجهة وفقًا للمتطلبات الجديدة. عادة ما نقوم بإنشاء واجهات مع التبعيات الخارجية من أجل أن تكون قادرة على إجراء الاختبارات محليا.
يسمح هذا النهج للمستخدم بتنفيذ واجهاته الصغيرة الخاصة به ببساطة عن طريق لف جزء من المكتبة للاختبار. لمزيد من المعلومات حول هذا المفهوم ، اقرأ
مقالة rakyl عن تلوث الواجهة .
لا تقم بتصدير بدائل التزامنتقدم Go أدوات أولية سهلة الاستخدام يمكن أن تؤدي في بعض الأحيان إلى الإفراط في استخدامها بسبب البساطة نفسها. بادئ ذي بدء ، نحن قلقون بشأن القنوات وحزمة المزامنة. أحيانًا يكون من المغري تصدير قناة من الحزمة الخاصة بك حتى يتمكن الآخرون من استخدامها. بالإضافة إلى ذلك ، هناك خطأ شائع يتمثل في تضمين
sync.Mutex
دون
sync.Mutex
على خاص. هذا ، كالعادة ، ليس سيئًا دائمًا ، ولكنه يخلق مشاكل معينة عند اختبار البرنامج.
إذا قمت بتصدير القنوات ، فإنك تزيد من تعقيد حياة مستخدم الحزمة ، وهو أمر لا يستحق القيام به. بمجرد أن يتم تصدير القناة من الحزمة ، فإنك تخلق صعوبات عند اختبار الشخص الذي يستخدم هذه القناة. لاختبار ناجح ، يجب على المستخدم معرفة:
- عندما تنتهي البيانات يتم إرسالها عبر القناة.
- كان هناك أي أخطاء عند تلقي البيانات.
- كيف تقوم الحزمة بمسح القناة بعد اكتمالها ، إذا كان التدفق على الإطلاق؟
- كيفية التفاف حزمة واجهة برمجة التطبيقات (API) للحزمة حتى لا تتصل بها مباشرة؟
ألقِ نظرة على مثال قائمة انتظار القراءة. فيما يلي مكتبة نموذجية تقرأ من قائمة الانتظار وتوفر للمستخدم موجزًا للقراءة.
type Reader struct {...} func (r *Reader) ReadChan() <-chan Msg {...}
الآن يريد مستخدم مكتبتك تنفيذ اختبار للمستهلك:
func TestConsumer(t testing.T) { cons := &Consumer{ r: libqueue.NewReader(), } for msg := range cons.r.ReadChan() {
يمكن للمستخدم بعد ذلك أن يقرر أن حقن التبعية فكرة جيدة وأن يكتب رسائله الخاصة في القناة:
func TestConsumer(t testing.T, q queueIface) { cons := &Consumer{ r: q, } for msg := range cons.r.ReadChan() {
الانتظار ، ماذا عن الأخطاء؟
func TestConsumer(t testing.T, q queueIface) { cons := &Consumer{ r: q, } for { select { case msg := <-cons.r.ReadChan():
نحتاج الآن إلى إنشاء أحداث بطريقة ما من أجل الكتابة فعليًا إلى هذا العنصر ، الذي يكرر سلوك المكتبة التي نستخدمها. إذا كانت المكتبة قد كتبت للتو واجهة برمجة التطبيقات المتزامنة ، فيمكننا إضافة كل التوازي إلى رمز العميل ، لذلك يصبح الاختبار أسهل.
func TestConsumer(t testing.T, q queueIface) { cons := &Consumer{ r: q, } msg, err := cons.r.ReadMsg()
إذا كنت في شك ، فقط تذكر أنه من السهل دائمًا إضافة التوازي إلى حزمة المستهلك (الحزمة المستهلكة) ، ومن الصعب أو المستحيل إزالتها بعد التصدير من المكتبة. والأهم من ذلك ، لا تنسى أن تكتب في وثائق الحزمة ما إذا كانت البنية / الحزمة آمنة للوصول المتزامن إلى العديد من goroutines.
في بعض الأحيان لا يزال من المرغوب فيه أو الضروري تصدير القناة. للتخفيف من بعض المشاكل المذكورة أعلاه ، يمكنك توفير قنوات من خلال accessors بدلاً من الوصول المباشر وتركها مفتوحة فقط للقراءة (
←chan
) أو فقط للكتابة (
chan←
) عند الإعلان.
استخدم net/http/httptest
يتيح
Httptest
http.Handler
تنفيذ التعليمات البرمجية
http.Handler
دون بدء تشغيل خادم أو ربط منفذ. هذا يسرع الاختبار ويسمح لك بإجراء الاختبارات في وقت واحد بتكلفة أقل.
فيما يلي مثال على الاختبار نفسه الذي تم تنفيذه بطريقتين. لا يوجد شيء عجيب هنا ، ولكن هذا النهج يقلل من مقدار التعليمات البرمجية ويوفر الموارد.
func TestServe(t *testing.T) {
ولعل أهم ميزة هي أنه مع
httptest
يمكنك فقط تقسيم الاختبار إلى الوظيفة التي تريد اختبارها. لا توجد أجهزة توجيه أو برامج وسيطة أو أي آثار جانبية أخرى تنشأ عند إعداد الخوادم أو الخدمات أو مصانع المعالجات أو مصانع المعالجات أو أي أشياء أخرى تعتقد أنها ستكون فكرة جيدة.
لرؤية هذا المبدأ في التطبيق ، راجع
مقالة مارك بيرغر .
استخدام حزمة منفصلة _test
يتم إنشاء معظم الاختبارات في النظام البيئي في ملفات
pkg_test.go
، ولكن لا تزال في نفس الحزمة:
package pkg
. حزمة اختبار منفصلة هي الحزمة التي تنشئها في الملف الجديد ،
foo_test.go
، في دليل الوحدة التي تريد اختبارها ،
foo/
، مع
package foo_test
التصريح
package foo_test
. من هنا ، يمكنك استيراد
github.com/example/foo
والتبعيات الأخرى. تتيح لك هذه الميزة القيام بأشياء كثيرة. هذا هو الحل الموصى به للتبعيات الدورية في الاختبارات ، حيث يمنع ظهور "الاختبارات الهشة" ويسمح للمطور أن يشعر بما يشبه استخدام الحزمة الخاصة بك. إذا كان من الصعب استخدام الحزمة الخاصة بك ، فسيكون الاختبار بهذه الطريقة أيضًا صعبًا.
تمنع هذه الاستراتيجية الاختبارات الهشة من خلال تقييد الوصول إلى المتغيرات الخاصة. على وجه الخصوص ، إذا تعطلت اختباراتك واستخدمت حزم اختبار منفصلة ، فمن شبه المؤكد أن العميل الذي يستخدم دالة تقطعها الاختبارات سوف ينقطع عند الاتصال.
أخيرًا ، يساعد على تجنب دورات الاستيراد في الاختبارات. غالبًا ما تعتمد معظم الحزم على الحزم الأخرى التي كتبتها إلى جانب الحزم الاختبارية ، لذلك ستنتهي بموقف تحدث فيه دورة الاستيراد بشكل طبيعي. توجد حزمة خارجية أعلى الحزمتين في التسلسل الهرمي للحزمة. خذ مثالاً من لغة برمجة Go (الفصل 11 ، القسم 2.4) ، حيث يقوم
net/url
بتنفيذ محلل عناوين URL الذي يستورده
net/http
للاستخدام. ومع ذلك ، يجب اختبار
net / url
مع حالة استخدام حقيقية عن طريق استيراد
net / http
. وبالتالي
net/url_test
.
الآن ، عند استخدام حزمة اختبار منفصلة ، قد تحتاج إلى الوصول إلى كيانات غير مستوردة في الحزمة حيث كانت متوفرة مسبقًا. يواجه بعض المطورين هذا لأول مرة عند اختبار شيء بناءً على الوقت (على سبيل المثال ، time.Now يصبح كعب روتين باستخدام دالة). في هذه الحالة ، يمكننا استخدام ملف إضافي لتوفير كيانات بشكل خاص أثناء الاختبار ، حيث
_test.go
استبعاد ملفات
_test.go
عمليات
_test.go
العادية.
ماذا تحتاج أن تتذكر؟من المهم أن تتذكر أن أيًا من الطرق الموضحة أعلاه ليست حلاً سحريًا. أفضل طريقة في أي عمل هي تحليل الموقف بشكل نقدي واختيار أفضل حل للمشكلة بشكل مستقل.
هل تريد معرفة المزيد حول الاختبار باستخدام Go؟
اقرأ هذه المقالات:
ديف تشيني جدول الكتابة مدفوعة الاختبارات في الذهابفصل لغة برمجة الذهاب في الاختبار.أو شاهد مقاطع الفيديو هذه:
حديث هاشيموتو المتقدم مع Go يتحدث من Gophercon 2017الحديث عن تقنيات اختبار أندرو جيراند من 2014نأمل أن تكون هذه الترجمة مفيدة لك. نحن في انتظار التعليقات ، وكل من يريد معرفة المزيد عن الدورة ، ندعوك
لفتح يوم ، والذي سيعقد في 23 مايو.