التكامل المستمر CI وبيئات الاختبار
كيف نضمن أن الاختبارات تُشغَّل فعلًا، وأن الكود المكسور لا يمرّ؟ ⏱ نحو 40 دقيقة.
- تفهم التكامل المستمر
CI. - تدرك كيف يمنع
CIدمج الكود المكسور. - تفصل بيئات التطوير والاختبار والإنتاج.
- تعزل بيانات الاختبار.
١الاختبار الذي يعمل وحده
اختباراتٌ ممتازة لا يشغّلها أحد عديمة الفائدة. التكامل المستمر CI يحلّ ذلك: خادمٌ يشغّل مجموعة الاختبارات آليًّا عند كل تغييرٍ يُرفَع إلى المستودع. إن فشل اختبار، يُمنَع الدمج ويُنبَّه الفريق فورًا. فلا يصل عيبٌ إلى الفرع الرئيس.
| بلا CI | مع CI |
|---|---|
| «نسيت تشغيل الاختبارات» | تُشغَّل آليًّا دائمًا |
| العيب يُكتشَف متأخّرًا | يُكتشَف لحظة رفع الكود |
| «يعمل عندي فقط» | يُبنى ويُختبَر في بيئةٍ نظيفة موحّدة |
CI يحوّل الاختبار من عادةٍ فرديةٍ منسيّة إلى بوّابةٍ آلية. هو ما يجعل اختبار الانحدار (الدرس السابق) حقيقةً دائمة لا نيّةً حسنة.
٢كيف يبدو إعداد CI
ملفٌّ بسيط يصف ما يُشغَّل عند كل رفع (مثال GitHub Actions). الفكرة: ثبّت، ثم اختبر، وافشل البناء إن فشل اختبار:
# ci.yml — GitHub Actionsname: tests on: [push, pull_request] # عند كل رفعٍ أو طلب دمج jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pip install -r requirements.txt - run: pytest --cov # يفشل البناء إن فشل اختبار
عند كل push: يجلب الكود، يثبّت الاعتمادات، يشغّل pytest مع التغطية. نتيجةٌ خضراء تسمح بالدمج، وحمراء تمنعه.
٣بيئات الاختبار
لا نختبر على بيئة المستخدمين الحيّة. نفصل البيئات كي لا يؤثّر الاختبار على الإنتاج:
| البيئة | الغرض |
|---|---|
| التطوير Dev | جهاز المبرمج؛ اختبارات سريعة أثناء الكتابة |
| الاختبار / التكامل Test | بيئة نظيفة يشغّلها CI؛ تشبه الإنتاج |
| التجهيز Staging | نسخة طبق الأصل للإنتاج؛ اختبار القبول النهائيّ |
| الإنتاج Production | المستخدمون الحقيقيّون؛ لا نختبر عليها |
توقّع وتحقّق
CI يشغّل الاختبارات:
إن فشل اختبارٌ في CI:
لا نختبر على بيئة:
بيانات الاختبار يجب أن تكون:
الخلاصة
CIيشغّل الاختبارات آليًّا عند كل تغيير، ويمنع دمج الكود المكسور.- يحوّل الاختبار من عادةٍ منسيّة إلى بوّابةٍ آلية دائمة.
- افصل البيئات: تطوير، اختبار، تجهيز، إنتاج — ولا تختبر على الإنتاج.
- اعزل بيانات الاختبار؛ لا تستخدم بيانات المستخدمين الحقيقية.
تحدٍّ برمجي: بوّابة CI
متوسطحاكِ بوّابة CI: دالة ci_gate تأخذ قائمة نتائج اختبارات (True=نجح) وتعيد "pass" إن نجحت كلّها وإلا "fail". اطبع نتيجة مجموعتين.
- أعِد
"pass"فقط إن كانت كل النتائج True. - اطبع نتيجة
[True,True,True]و[True,False,True].
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
def ci_gate(results): # "pass" إن نجحت كل الاختبارات وإلا "fail" passprint(ci_gate([True, True, True]))print(ci_gate([True, False, True]))
💡 تلميح 1
all(results) يكون True إن نجحت كلّها.💡 تلميح 2
return "pass" if all(results) else "fail".حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
def ci_gate(results): return "pass" if all(results) else "fail"print(ci_gate([True, True, True]))print(ci_gate([True, False, True]))