عند كتابة الشيفرة في Python، من المهم التأكد من أن الشيفرة تعمل كما هو متوقع. واحدة من أفضل الطرق للقيام بذلك هي استخدام اختبارات الوحدة، التي تساعدك على التحقق مما إذا كانت الأجزاء الصغيرة (أو الوحدات) من شيفرتك تعمل بشكل صحيح.
في هذه المقالة، سنتعلم كيفية كتابة وتشغيل اختبارات وحدة فعالة في Python باستخدام PyTest، أحد أكثر أطر الاختبار شعبية في Python.
ما هي اختبارات الوحدة؟
اختبارات الوحدة هي اختبارات صغيرة وبسيطة تركز على التحقق من وظيفة واحدة أو قطعة صغيرة من الشيفرة. تساعد في ضمان أن الشيفرة الخاصة بك تعمل كما هو متوقع ويمكن أن تكتشف الأخطاء مبكرًا.
يمكن كتابة اختبارات الوحدة لأجزاء مختلفة من الشيفرة الخاصة بك، مثل الوظائف، والطرق، وحتى الفئات. من خلال كتابة اختبارات الوحدة، يمكنك اختبار الشيفرة الخاصة بك دون تشغيل البرنامج بالكامل.
لماذا نستخدم PyTest؟
PyTest هو إطار اختبار شائع لـ Python يجعل من السهل كتابة وتشغيل الاختبارات.
إنه سهل الاستخدام ويحتوي على العديد من الميزات المفيدة مثل:
- يسمح لك بكتابة حالات اختبار بسيطة وواضحة.
- يوفر ميزات متقدمة مثل الإعدادات، والاختبارات المعلمة، والإضافات.
- يعمل بشكل جيد مع أدوات ومكتبات الاختبار الأخرى.
- ينتج نتائج وتقارير اختبارات سهلة القراءة.
إعداد PyTest في لينكس
قبل أن نبدأ في كتابة الاختبارات، نحتاج إلى تثبيت PyTest. إذا لم يكن لديك PyTest مثبتًا، يمكنك تثبيته باستخدام مدير حزم بايثون المعروف باسم pip.
pip install pytest
بمجرد تثبيت PyTest، ستكون مستعدًا لبدء كتابة الاختبارات!
كتابة أول اختبار لك باستخدام PyTest
لنبدأ بكتابة دالة بسيطة ثم نكتب اختبارًا لها.
الخطوة 1: كتابة دالة بسيطة
أولاً، دعنا ننشئ دالة بايثون نريد اختبارها. لنفترض أن لدينا دالة تجمع عددين:
# add.py def add(a, b): return a + b
هذه دالة بسيطة تأخذ عددين a و b، تجمعهما معًا، وتعيد النتيجة.
الخطوة 2: كتابة اختبار للدالة
الآن، دعنا نكتب اختبارًا لدالة الجمع. في PyTest، تُكتب الاختبارات في ملفات منفصلة، وعادةً ما تُسمى test_*.py
لتسهيل تحديد ملفات الاختبار.
أنشئ ملفًا جديدًا يسمى test_add.py
واكتب كود الاختبار التالي:
# test_add.py from add import add def test_add_numbers(): assert add(2, 3) == 5 assert add(-1, 1) == 0 assert add(0, 0) == 0
شرح الكود أعلاه:
- نقوم باستيراد دالة
add
من ملفadd.py
. - نقوم بتعريف دالة اختبار تسمى
test_add_numbers()
. في PyTest، يجب أن تبدأ دالة الاختبار بكلمةtest_
. - داخل دالة الاختبار، نستخدم عبارة
assert
للتحقق مما إذا كانت نتيجة استدعاء دالةadd
تتطابق مع القيمة المتوقعة. إذا كانت الشرط في عبارةassert
هوTrue
، فإن الاختبار ينجح؛ وإلا فإنه يفشل.
الخطوة 3: تشغيل الاختبار
لتشغيل الاختبار، افتح الطرفية الخاصة بك وانتقل إلى الدليل حيث يوجد ملف test_add.py
ثم قم بتشغيل الأمر التالي:
pytest
سيقوم PyTest بالعثور تلقائيًا على جميع ملفات الاختبار (التي تبدأ بـ test_
) وتشغيل الاختبارات داخلها. إذا كان كل شيء يعمل بشكل صحيح، يجب أن ترى مخرجات مثل هذه:

النقطة (.)
تشير إلى أن الاختبار قد اجتاز. إذا كان هناك أي مشاكل، فإن PyTest سيظهر رسالة خطأ.
كتابة اختبارات أكثر تقدمًا
الآن بعد أن عرفنا كيفية كتابة وتشغيل اختبار أساسي، دعونا نستكشف بعض الميزات الأكثر تقدمًا لـ PyTest.
اختبار الاستثناءات المتوقعة
أحيانًا، تريد اختبار ما إذا كان الكود الخاص بك يثير الاستثناءات الصحيحة عندما يحدث شيء خاطئ. يمكنك القيام بذلك باستخدام دالة pytest.raises()
.
دعنا نقول أننا نريد اختبار دالة تقسم عددين. نريد أن نثير استثناء إذا كان العدد الثاني صفرًا (لتجنب أخطاء القسمة على صفر).
إليك دالة divide
:
# divide.py def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b
الآن، دعنا نكتب اختبارًا لهذه الدالة يتحقق مما إذا كان ValueError
يُثار عندما نحاول القسمة على صفر:
# test_divide.py from divide import divide import pytest def test_divide_numbers(): assert divide(10, 2) == 5 assert divide(-10, 2) == -5 assert divide(10, -2) == -5 def test_divide_by_zero(): with pytest.raises(ValueError): divide(10, 0)
شرح الكود:
- أضفنا وظيفة اختبار جديدة تسمى
test_divide_by_zero()
. - داخل هذه الوظيفة، نستخدم
pytest.raises(ValueError)
للتحقق مما إذا كانتValueError
يتم رفعها عند استدعاء دالة القسمة مع الصفر كوسيط ثانٍ.
قم بتشغيل الاختبارات مرة أخرى باستخدام أمر pytest. إذا كان كل شيء يعمل بشكل صحيح، يجب أن ترى هذا المخرج:

استخدام التهيئات للإعداد والتنظيف
في بعض الحالات، قد تحتاج إلى إعداد ظروف معينة قبل تشغيل اختباراتك أو تنظيفها بعد الانتهاء من الاختبارات. PyTest يوفر تهيئات للتعامل مع ذلك.
التهيئة هي دالة يمكنك استخدامها لإعداد أو إنهاء الظروف لاختباراتك. وغالبًا ما تُستخدم التهيئات لإنشاء كائنات أو الاتصال بقواعد البيانات اللازمة للاختبارات.
إليك مثال على استخدام تهيئة لإعداد دليل مؤقت لاختبار عمليات الملفات:
# test_file_operations.py import pytest import os @pytest.fixture def temporary_directory(): temp_dir = "temp_dir" os.mkdir(temp_dir) yield temp_dir # This is where the test will run os.rmdir(temp_dir) # Cleanup after the test def test_create_file(temporary_directory): file_path = os.path.join(temporary_directory, "test_file.txt") with open(file_path, "w") as f: f.write("Hello, world!") assert os.path.exists(file_path)
شرح الكود:
- نقوم بتعريف تهيئة تسمى
temporary_directory
التي تنشئ دليلًا مؤقتًا قبل الاختبار وتحذفه بعد ذلك. - تستخدم دالة الاختبار
test_create_file()
هذه التهيئة لإنشاء ملف في الدليل المؤقت والتحقق مما إذا كان الملف موجودًا.
قم بتشغيل الاختبارات مرة أخرى باستخدام أمر pytest. سيتعرف PyTest تلقائيًا على التهيئة ويستخدمها.
قم بتمرير معلمات اختباراتك باستخدام Pytest
أحيانًا، تريد تشغيل نفس الاختبار مع مدخلات مختلفة. PyTest يتيح لك القيام بذلك بسهولة باستخدام parametrize.
لنقل أننا نريد اختبار دالة add
الخاصة بنا مع عدة أزواج من الأرقام. بدلاً من كتابة دوال اختبار منفصلة لكل زوج، يمكننا استخدام pytest.mark.parametrize
لتشغيل نفس الاختبار بمدخلات مختلفة.
# test_add.py import pytest from add import add @pytest.mark.parametrize("a, b, expected", [ (2, 3, 5), (-1, 1, 0), (0, 0, 0), (100, 200, 300) ]) def test_add_numbers(a, b, expected): assert add(a, b) == expected
شرح الكود:
- نستخدم مزيج
pytest.mark.parametrize
لتعريف مجموعات متعددة من المدخلات (a
،b
، وexpected
). - سيتم تشغيل الاختبار
function test_add_numbers()
مرة واحدة لكل مجموعة من المدخلات.
قم بتشغيل الاختبارات مرة أخرى باستخدام أمر pytest، والذي سيقوم بتشغيل الاختبار أربع مرات، مرة لكل مجموعة من المدخلات.
الخاتمة
في هذه المقالة، تعلمنا كيفية كتابة وتشغيل اختبارات وحدات فعالة في Python باستخدام PyTest لاكتشاف الأخطاء مبكرًا وضمان أن الكود الخاص بك يعمل كما هو متوقع.
PyTest يجعل من السهل كتابة وتشغيل هذه الاختبارات، ومع ميزاته القوية، يمكنك التعامل مع احتياجات اختبار أكثر تعقيدًا مع تقدمك في رحلة Python الخاصة بك.
Source:
https://www.tecmint.com/unit-testing-python-code-with-pytest/