كيفية إجراء الاختبارات الوحدوية في Python باستخدام unittest
تمت الكتابة بواسطة: عبد الحكيم
تارخ آخر تحديث: 10 سبتمبر 2024محتوى المقال
- لماذا تعتبر الاختبارات الوحدوية مهمة؟
- تثبيت واستخدام مكتبة unittest
- كيفية تشغيل الاختبارات
- أمثلة متقدمة في كتابة الاختبارات
- أفضل الممارسات في كتابة الاختبارات الوحدوية
- الخلاصة
تعتبر الاختبارات الوحدوية (Unit Tests) جزءًا أساسيًا من عملية تطوير البرمجيات، حيث تساعد المطورين في التحقق من أن الوحدات الفردية (مثل الدوال أو الكلاسات) تعمل كما هو متوقع. في لغة البرمجة Python، تعد مكتبة unittest
واحدة من الأدوات الأساسية التي تمكن المطورين من كتابة اختبارات وحدوية بطريقة منظمة وسهلة الاستخدام. في هذا المقال، سنتعرف على كيفية استخدام مكتبة unittest
لإجراء الاختبارات الوحدوية، وسنستعرض أمثلة عملية على ذلك.
لماذا تعتبر الاختبارات الوحدوية مهمة؟
الاختبارات الوحدوية تساعد في ضمان أن كل جزء من الكود يعمل بشكل صحيح كما هو متوقع. بالإضافة إلى ذلك، تسهم هذه الاختبارات في تحسين جودة البرمجيات من خلال:
- اكتشاف الأخطاء والمشاكل في وقت مبكر من دورة حياة التطوير.
- توفير توثيق ضمني للكود عن طريق وصف كيفية توقع عمل الوحدات الفردية.
- تسهيل عملية إعادة كتابة الكود أو تحسينه (Refactoring) دون الخوف من كسر شيء ما.
- ضمان استقرار الكود على المدى الطويل عند إدخال تغييرات أو تحسينات جديدة.
تثبيت واستخدام مكتبة unittest
تأتي مكتبة unittest
مدمجة مع Python، مما يعني أنك لست بحاجة إلى تثبيتها بشكل منفصل. يمكنك بدء استخدام unittest
مباشرة بكتابة الاختبارات في ملفات Python الخاصة بك.
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
with self.assertRaises(TypeError):
s.split(2)
if __name__ == "__main__":
unittest.main()
في هذا المثال، نقوم بكتابة ثلاثة اختبارات بسيطة للتحقق من وظائف سلسلة نصية (String). الدالة test_upper()
تتحقق من أن الدالة upper()
تحول النص إلى حروف كبيرة، بينما تتحقق الدالة test_isupper()
من أن النص يتكون بالكامل من حروف كبيرة. أما الدالة test_split()
فتتحقق من أن الدالة split()
تقوم بتقسيم النص بشكل صحيح.
كيفية تشغيل الاختبارات
لتشغيل الاختبارات التي كتبتها باستخدام unittest
، يمكنك استخدام سطر الأوامر (Command Line) ببساطة، عن طريق تنفيذ الملف الذي يحتوي على الاختبارات:
$ python test_example.py
سيقوم unittest
بتشغيل جميع الدوال التي تبدأ بــ test_
ويعرض النتائج. إذا كانت جميع الاختبارات ناجحة، ستظهر رسالة OK
، وإلا سيتم عرض معلومات حول الاختبارات التي فشلت.
أمثلة متقدمة في كتابة الاختبارات
بينما يعتبر المثال السابق بسيطًا، هناك العديد من المميزات المتقدمة التي يوفرها unittest
مثل إعداد الاختبارات وتفكيكها (Setup and Teardown)، واستخدام التوكيلات الوهمية (Mocking)، وإجراء اختبارات متعددة الجوانب (Parameterized Tests).
إعداد وتفكيك الاختبارات
يمكنك استخدام الدوال setUp()
و tearDown()
لتنفيذ أكواد معينة قبل وبعد كل اختبار. على سبيل المثال، قد ترغب في إعداد بعض البيانات أو الموارد المشتركة للاختبارات:
import unittest
class TestDatabase(unittest.TestCase):
def setUp(self):
# إنشاء اتصال بقاعدة البيانات
self.connection = create_connection()
def tearDown(self):
# إغلاق الاتصال بقاعدة البيانات
self.connection.close()
def test_insert(self):
# اختبار إدخال بيانات في قاعدة البيانات
self.assertTrue(insert_data(self.connection, data))
if __name__ == "__main__":
unittest.main()
في هذا المثال، نستخدم setUp()
لإعداد الاتصال بقاعدة البيانات قبل كل اختبار، وtearDown()
لإغلاق الاتصال بعد انتهاء الاختبار. هذا يضمن أن جميع الاختبارات التي تتطلب الاتصال بقاعدة البيانات يمكن أن تعتمد على نفس بيئة الإعداد.
استخدام التوكيلات الوهمية (Mocking)
في بعض الأحيان، قد تحتاج إلى محاكاة (Mock) بعض الدوال أو الكائنات أثناء الاختبار. هذا يكون مفيدًا عندما ترغب في اختبار وحدة دون الاعتماد على الوحدات الخارجية مثل قواعد البيانات أو واجهات برمجة التطبيقات الخارجية.
from unittest import mock
class TestPayment(unittest.TestCase):
@mock.patch('payment_gateway.charge')
def test_charge(self, mock_charge):
mock_charge.return_value = True
self.assertTrue(process_payment(amount))
if __name__ == "__main__":
unittest.main()
في هذا المثال، نقوم بمحاكاة الدالة charge()
الخاصة ببوابة الدفع للتأكد من أن دالة process_payment()
تعمل بشكل صحيح دون الحاجة إلى تنفيذ العملية الفعلية.
أفضل الممارسات في كتابة الاختبارات الوحدوية
لكتابة اختبارات وحدوية فعالة في Python، هنا بعض النصائح التي يمكنك اتباعها:
- اجعل الاختبارات بسيطة ومركزة: يجب أن يختبر كل اختبار وظيفة أو سلوك واحد فقط. هذا يسهل تحديد مصدر الخطأ عند فشل الاختبار.
- استخدم أسماء واضحة للدوال: اختر أسماء تصف بوضوح ما يفعله الاختبار، مثل
test_addition_of_two_numbers()
. - قم بتغطية الحالات الحديّة: تأكد من اختبار الحالات التي يمكن أن تسبب مشاكل، مثل القيم الصفرية أو القيم الكبيرة جدًا.
- تحقق من الأداء: في بعض الحالات، قد تحتاج إلى التحقق من أداء الكود، خاصة إذا كان الكود يعتمد على الحلقات أو العمليات المكثفة.
- اجعل الاختبارات مستقلة: لا تعتمد على نتائج اختبارات أخرى، كل اختبار يجب أن يكون قادرًا على العمل بمفرده.
الخلاصة
تعتبر مكتبة unittest
أداة قوية ومرنة لإجراء الاختبارات الوحدوية في Python. من خلال اعتماد أفضل الممارسات وفهم كيفية استخدام الميزات المختلفة مثل إعداد وتفكيك الاختبارات، واستخدام التوكيلات الوهمية، يمكنك تحسين جودة كودك وضمان استقراره على المدى الطويل. تأكد من أن تجعل الاختبارات جزءًا أساسيًا من عملية التطوير، وسترى الفوائد الكبيرة التي تجنيها من ذلك.
طور مهاراتك: مقالات يجب قراءتها في البرمجة
- بناء تطبيق ويب بسيط باستخدام Django في Python
- كيفية استخدام مكتبة Seaborn لإنشاء مخططات متقدمة في Python
- كيفية إرسال رسائل بريد إلكتروني باستخدام Python
- كيفية التعامل مع النصوص الكبيرة باستخدام مكتبة StringIO في Python
- كيفية استخدام مكتبة Socket لبرمجة الشبكات في Python
- كيفية تحليل البيانات البيانية باستخدام مكتبة Plotly في Python
- إنشاء تطبيق ويب ديناميكي باستخدام FastAPI في Python
- كيفية إدارة وحفظ الملفات باستخدام مكتبة os في Python
- كيفية كتابة سكربت لتشغيل أوامر النظام في Python
- كيفية استخدام مكتبة pathlib لإدارة الملفات والمسارات في Python