Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Python
Code

كتابة اختبارات الوحدة الفنية في Python

by
Difficulty:IntermediateLength:LongLanguages:

Arabic (العربية/عربي) translation by Muhammad Hakim Almadani (you can also view the original English article)

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

تشغيل المثال

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

هنا اختبار وحدة لأسلوب stop () لشحذ شهيتك. سوف ندخل التفاصيل لاحقاً.

المبادئ التوجيهية لاختبار وحدة

ارتكاب

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

تكون منضبطة

يجب أن تكون منضبطة. أن تكون متسقة. تأكد من اجتياز الاختبارات دائماً. لا تدع الاختبارات تكون مكسورة لأنك "تعرف" التعليمة البرمجية هو موافق.

أتمتة

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

يتم تقسيم التعليمات البرمجية التي لم يتم اختبارها بتعريف

إذا لم يمكنك اختبار ذلك، لا يمكنك القول أنه يعمل. وهذا يعني أن عليك أن تنظر في ذلك كسر. إذا كانت التعليمات البرمجية الحرجة، لا نشر ذلك للإنتاج.

معلومات أساسية

ما هي وحدة؟

وحدة لغرض اختبار وحدة ملف/وحدة تحتوي على مجموعة من المهام ذات الصلة أو فئة. إذا كان لديك ملف مع فئات متعددة، يجب عليك كتابة اختبار وحدة لكل فئة.

TDD أو عدم TDD

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

والسبب أن أنا تصميم مع التعليمات البرمجية. اكتب التعليمات البرمجية، ننظر في الأمر وكتابتها، وننظر في الأمر مرة أخرى وإعادة كتابتها مرة أخرى بشكل سريع جداً. كتابة اختبارات أول تحد لي ويبطئ لي.

مرة واحدة وأنا فعلت مع التصميم الأولى، أنا اكتب الاختبارات على الفور، قبل الاندماج مع بقية النظام. وقال أن، أنها طريقة رائعة لتقديم نفسك لاختبارات الوحدة، ويضمن أنه سيكون كافة التعليمات البرمجية الخاصة بك للاختبارات.

الوحدة النمطية أونيتيست

الوحدة unittest أونيتيست يأتي مع مكتبة بيثون القياسية. يوفر فئة تسمى TestCase التي يمكنك اشتقاق الفئة الخاصة بك من. ثم يمكنك تجاوز أسلوب ()setUp أن تعد لاعبا اختبار قبل كل اختبار و/أو أسلوب فئة ()classSetUp لإعداد لاعبا اختبار لكافة الاختبارات (عدم إعادة تعيين بين الاختبارات الفردية). هي المقابلة هناك أساليب ()tearDown و ()classTearDown ويمكنك تجاوز كذلك.

وفيما يلي الأجزاء ذات الصلة من فئة SelfDrivingCarTest لدينا. استخدام الأسلوب ()setUp فقط. قم بإنشاء مثيل SelfDrivingCar طازجة، وتخزينها في self.car حيث أنها متاحة لكل اختبار.

والخطوة التالية كتابة أساليب الاختبار المحددة لاختبار التعليمات البرمجية تحت الاختبار-الدرجة SelfDrivingCar في هذه الحالة – القيام بما أنه من المفترض أن تفعل. الهيكل لأسلوب الاختبار معيار جميلة:

  • إعداد البيئة (اختياري).
  • إعداد النتيجة المتوقعة.
  • استدعاء التعليمات البرمجية تحت الاختبار.
  • ويؤكد أن النتيجة الفعلية تطابق النتيجة المتوقعة.

لاحظ أن النتيجة لا يجب أن يكون الإخراج من أسلوب. يمكن أن يكون تغيير دولة من فئة، وآثار الجانبية مثل إضافة صف جديد في قاعدة بيانات أو كتابة ملف أو إرسال رسالة بريد إلكتروني.

على سبيل المثال، لا يرجع الأسلوب ()stop من فئة SelfDrivingCar أي شيء، ولكن تتغير الحالة الداخلية بتعيين السرعة إلى 0. يتم استخدام الأسلوب ()assertEqual المقدمة من الفئة الأساسية في TestCase هنا للتحقق من أن تطلق على ()stop يعمل كما هو متوقع.

وهناك فعلا من اختبارين هنا. أول اختبار للتأكد من أنه إذا كانت سرعة السيارة 5 و ()stop يسمى، ثم يصبح السرعة 0. ثم، اختبار آخر التأكد من أي شيء يذهب على نحو خاطئ في حالة استدعاء ()stop مرة أخرى عند إيقاف السيارة الفعل.

في وقت لاحق، سوف أعرض عدة اختبارات أكثر للحصول على وظائف إضافية.

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

الوحدة النمطية دوكتيست مثيرة جداً للاهتمام. وهو يتيح لك استخدام نماذج التعليمات البرمجية التفاعلية في دوكسترينج الخاص بك وتحقق من النتائج، بما في ذلك الاستثناءات التي آثارها.

أنا لا استخدم أو يوصي دوكتيست لنظم على نطاق واسع. اختبار وحدة السليم يتطلب الكثير من العمل. اختبار التعليمات البرمجية عادة أكبر بكثير من التعليمات البرمجية تحت الاختبار. دوكسترينجس ليست فقط المتوسط الصحيح لكتابة الاختبارات الشاملة. فباردة، على الرغم. هنا ما يبدو وكأنه وظيفة factorial مع الاختبارات doc:

كما ترون، أكبر بكثير من التعليمات البرمجية الدالة دوكسترينج. أنها لا تعزز قابلية القراءة.

تشغيل الاختبارات

كيلر وكتب لك اختبارات الوحدة الخاصة بك. لنظام كبيرة، سيكون لديك عشرات/مئات/آلاف من وحدات وفئات عبر ربما دلائل متعددة. كيف يمكنك تشغيل جميع هذه الاختبارات؟

الوحدة النمطية أونيتيست يوفر مرافق مختلفة لتجميع الاختبارات وتشغيلها برمجياً. تحقق من تحميل وتشغيل الاختبارات. ولكن أسهل طريقة اكتشاف الاختبار. تمت إضافة هذا الخيار فقط في 2.7 بيثون. ما قبل-2.7 يمكن استخدام nose لاكتشاف وتشغيل الاختبارات. وقد آنف بعض المزايا الأخرى مثل تشغيل اختبار وظائف دون الحاجة إلى إنشاء فئة لحالات الاختبار الخاصة بك. ولكن غرض هذه المقالة، دعونا العصا مع أونيتيست.

لاكتشاف وتشغيل الاختبارات الخاصة بك المستندة إلى أونيتيست، ببساطة اكتب في سطر الأوامر:

python -m unittest discover

سيتم مسح كافة الملفات والدلائل الفرعية أونيتيست وتشغيل أي الاختبارات التي يجدها وتقديم التقرير الجميل، فضلا عن وقت التشغيل. إذا كنت تريد أن ترى ما هي اختبارات تشغيله، يمكنك إضافة العلامة-v:

python -m unittest discover -v

هناك العديد من الإعلام التي تتحكم في هذه العملية:

اختبار التغطية

تغطية الاختبار حقل غالباً ما تهمل. التغطية يعني كم من التعليمات البرمجية الخاصة بك يتم فعلا اختبار من الاختبارات الخاصة بك. على سبيل المثال، إذا كان لديك دالة مع عبارة if-else ويمكنك اختبار فقط if كان فرع، ثم كنت لا تعرف ما إذا كان يعمل فرع else أم لا. في مثال التعليمة البرمجية التالي، يتحقق ()add الدالة نوع الوسيطات الخاصة بها. إذا كان كلا من الإعداد الصحيحة، فإنه يضيف فقط منهم.

إذا كان كلاهما السلاسل، فإنه يحاول تحويلها إلى إعداد صحيحة وتضيف إليها. إلا أنها تقوم بإصدار استثناء. الدالة ()test_add اختبار الدالة ()add مع الحجج التي إعداد صحيحة على حد سواء ومع الحجج التي يطفو والتحقق من السلوك الصحيح في كل حالة على حدة. ولكن تغطية الاختبار غير مكتملة. لم أكن اختبار حالة سلسلة الحجج. نتيجة لذلك ينجح الاختبار بنجاح، ولكن لم يكن اكتشف الخطأ المطبعي في الفرع حيث الحجج كلا سلاسل (انظر 'إينتج' هناك؟).

هنا هو الإخراج:

اختبارات وحدة التدريب العملي

كتابة اختبارات الوحدة القوة الصناعية ليست سهلة أو بسيطة. وهناك العديد من الأشياء للنظر والمقايضات بذل.

تصميم Testability

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

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

على سبيل المثال، لدينا فئة SelfDrivingCar مسؤولة عن عملية رفيعة المستوى للسيارة: الذهاب، وقف، والتنقل. أنها طريقة ()calculate_distance_to_object_in_front التي لم تنفذ حتى الآن. ربما ينبغي أن تنفذها هذه الوظيفة نظام فرعي منفصل تماما. وقد تشمل قراءة البيانات من مختلف أجهزة الاستشعار، وتتفاعل مع غيرها من السيارات ذاتية القيادة، كدسة رؤية جهاز كله لتحليل الصور من الكاميرات متعددة.

دعونا نرى كيف يعمل هذا في الممارسة العملية. SelfDrivingCar سوف تقبل وسيطة تسمى object_detector التي تحتوي على أسلوب يسمى ()calculate_distance_to_object_in_front ، وأنه سيتم تفويض هذه الوظيفة لهذا الكائن. الآن، ليس هناك أي حاجة لوحدة اختبار هذا نظراً object_detector هو المسؤول (وينبغي اختبار) لأنه. كنت لا تزال تريد وحدة اختبار حقيقة أن كنت تستخدم في object_detector بشكل صحيح.

التكاليف والفوائد

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

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

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

اختبار عقلية

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

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

وظائف نقي

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

لماذا سهلة لاختبار؟ لأنه ليس هناك حاجة لتعيين بيئة خاصة لاختبار. يمكنك فقط تمرير الوسائط والنتيجة الاختبار. وتعلمون أيضا أن طالما لم يتم تغيير التعليمات البرمجية تحت الاختبار، اختبار الخاص بك لا يملك تغيير.

قارن ذلك إلى دالة تقوم بقراءة ملف تكوين XML. وسيكون الاختبار الخاص بك لإنشاء ملف XML وتمرير الملف به إلى التعليمات البرمجية تحت الاختبار. ليست صفقة كبيرة. ولكن لنفترض أن أحدهم قرر أن XML البغيضة، ويجب أن تكون كافة ملفات التكوين في JSON. أنها ممارسة أعمالهم وتحويل كافة ملفات التكوين إلى JSON. أنهم تشغيل كافة الاختبارات بما في ذلك الاختبارات الخاصة بك، وأنهم جميعا تمرير!

لماذا؟ لأنه لم يكن تغيير التعليمات البرمجية. أنها لا تزال تتوقع ملف تكوين XML، واختبار الخاص بك لا يزال يبني ملف XML لذلك. ولكن في الإنتاج، التعليمات البرمجية الخاصة بك سوف تحصل على ملف JSON، وأنها سوف تفشل في تحليل.

اختبار معالجة الخطأ

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

عادة، تحتاج إلى التحقق من الإدخال على الواجهة العمومية للتعليمات البرمجية الخاصة بك لأنك لا تعرف بالضرورة الذي يحدث لاستدعاء التعليمات البرمجية الخاصة بك. دعونا ننظر في الطريقة ()drive سيارة ذاتية القيادة. يتوقع هذا الأسلوب معلمة 'وجهة'. سيتم استخدام المعلمة 'وجهة' لاحقاً في التنقل، ولكن الأسلوب محرك الأقراص لا يفعل شيئا للتحقق من أنها صحيحة.

دعنا نفترض أن الوجهة من المفترض أن تكون مجموعة من خطوط الطول والعرض. هناك كل أنواع الاختبارات التي يمكن القيام به للتحقق من أنها صحيحة (مثل هو الوجهة في وسط البحر). لأغراضنا، دعونا فقط التأكد من أنها مجموعة عوامات في نطاق 0.0 إلى 90.0-180.0 إلى 180.0 لخط الطول والعرض.

هنا هو تحديث فئة SelfDrivingCar. أنا نفذت مسلي بعض الأساليب حبراً على ورق لأن استدعاء الأسلوب ()drive بعض هذه الطرق مباشرة أو غير مباشرة.

لاختبار خطأ معالجة في الاختبار، وسوف تمرير وسيطة غير صالحة والتحقق من أنها مرفوضة بشكل صحيح. يمكنك القيام بذلك باستخدام في ()self.assertRaises أسلوب unittest.TestCase. ينجح هذا الأسلوب إذا كانت التعليمات البرمجية تحت الاختبار في الواقع تقوم بإصدار استثناء.

دعونا نرى ذلك في العمل. الأسلوب ()test_drive بتمرير خطوط الطول والعرض خارج النطاق الصالح وتتوقع الأسلوب ()drive لرفع استثناء.

فشل الاختبار، لأن الأسلوب ()drive لا تحقق الوسيطات الخاصة بها لصحة ولا تقوم بإصدار استثناء. يمكنك الحصول على تقرير لطيفة مع معلومات كاملة حول ما فشلت، أين ولماذا.

لإصلاح ذلك دعونا تحديث الأسلوب ()drive الذي تحقق فعلا من نطاق الوسيطات الخاصة بها:

والآن، تمرير كافة الاختبارات.

اختبار الأساليب الخاصة

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

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

كيفية تنظيم اختبارات الوحدة الخاصة بك

في نظام كبير، أنها ليست دائماً واضحة كيفية تنظيم الاختبارات الخاصة بك. يجب أن يكون لديك ملف واحد كبير مع كافة الاختبارات لمجموعة، أو ملف اختبار واحد لكل فئة؟ ينبغي أن تكون الاختبارات في نفس ملف التعليمات البرمجية تحت الاختبار، أو في نفس الدليل؟

هنا هو استخدام النظام. الاختبارات يجب أن تكون منفصلة تماما عن التعليمات البرمجية تحت الاختبار (ومن ثم لا تستخدم دوكتيست). ومن الناحية المثالية، ينبغي أن تكون التعليمات البرمجية الخاصة بك في مجموعة. وينبغي أن الاختبارات لكل حزمة في دليل مشابهة للحزمة الخاصة بك. في دليل الاختبارات، ينبغي أن يكون هناك ملف واحد لكل وحدة نمطية من الحزمة الخاصة بك اسمه <test_<module name

على سبيل المثال، إذا كان لديك ثلاث وحدات في الحزمة الخاصة بك: module_1.py و ، module_2.py و module_3.py، يجب عليك اختبار ثلاثة ملفات: test_module_1.py و test_module_2.py و test_module_3.py تحت الدليل الاختبارات.

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

الاستنتاج

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

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.