دليلك الشامل لكتابة اختبارات الوحدات (Unit Testing) في PHP و Laravel باحترافية
يا مساء الفل على كل المبرمجين! بتجيلك اللحظة اللي بتعدل فيها حاجة بسيطة في الكود، وفجأة تلاقي النظام كله ضرب (Crash) والعميل بيكلمك في التليفون؟ كلنا مرينا بالموقف ده. الوجع ده هو السبب الرئيسي اللي بيخلينا نلجأ لحاجة اسمها اختبارات الوحدات (Unit Testing). النهاردة هنتكلم عن إزاي تضمن إن كودك في Laravel شغال زي الساعة باستخدام أدوات قوية زي PHPUnit و Pest.
Table of contents [Show]
في البداية، ممكن تشوف الموضوع مضيعة للوقت، لكن الحقيقة إن الـ Automated Testing بيوفر عليك وقت ومجهود خرافي في مرحلة الـ Debugging. لما بتكتب Test، أنت بتعمل لنفسك شبكة أمان (Safety Net). لو غيرت أي جزء في الـ Logic الخاص بيك، بمجرد ما تشغل الاختبارات هتعرف فوراً لو فيه حاجة اتكسرت من غير ما تضطر تجرب كل زرار في الموقع يدوياً.
الفرق بين PHPUnit و Pest في لارافيل
لحد وقت قريب، كان PHPUnit هو الملك المتوج، وهو فعلاً الأساس اللي مبني عليه كل حاجة. لكن مؤخراً ظهر Pest، وهو إطار عمل اختبارات مبني فوق PHPUnit بيخلي كتابة الاختبارات ممتعة وقريبة جداً للغة البشر (Human-readable). يعني بدل ما تكتب كود تقني معقد، بتكتب وصف للحالة اللي بتختبرها.
كتابة الاختبارات مش مجرد كود، دي عقلية. عشان تطلع اختبارات قوية، اتبع القواعد دي:
- اختبار وحدة واحدة فقط: الـ Unit Test لازم يركز على Method واحدة أو Class واحد. لا تختبر نظام كامل في اختبار واحد.
- الاستقلالية (Isolation): الاختبار بتاعك مش لازم يعتمد على قاعدة بيانات حقيقية أو سيرفر خارجي. استخدم الـ Mocking عشان تحاكي الـ External Dependencies.
- التسمية الواضحة: سمي الاختبار بتاعك باسم يوضح هو بيعمل إيه، مثلاً
it_can_calculate_user_total_ordersبدلاً منtest_function_1.
مثال عملي باستخدام Pest
تعال نشوف إزاي بنكتب اختبار بسيط في Laravel باستخدام Pest. لو عندنا Service بتحسب سعر الخصم:
it('calculates the discount correctly', function () {
$calculator = new DiscountCalculator();
$result = $calculator->apply(100, 20);
expect($result)->toBe(80);
});
لاحظ البساطة! الكود بيشرح نفسه. الـ Expectation API في Pest بيخلي قراءة الاختبار سهلة جداً لأي حد يراجع الكود وراك.
استخدام الـ Mocking في Laravel
في أغلب الأحيان، الكود بتاعك بيتعامل مع API أو Database. هنا بيجي دور الـ Mocking. لارافيل موفرلك أدوات خرافية زي mock() عشان تتأكد إن الكود بتاعك بيبعت البيانات الصح للسيرفر التاني من غير ما فعلاً تبعت ريكويست حقيقي.
it('sends an email to the user', function () {
Mail::fake();
// إجراء العملية اللي بتبعت إيميل
$this->post('/register', [...]);
Mail::assertSent(WelcomeEmail::class);
});
نصيحة من أخ لمبرمج زيه
يا صديقي، ماتحاولش تكتب Test Coverage بنسبة 100% من أول يوم. ابدأ بالـ Critical Paths، يعني المناطق الحساسة في تطبيقك (زي نظام الدفع أو التسجيل). مع الوقت، كتابة الاختبارات هتتحول لـ Habit (عادة) عندك، وهتلاقي نفسك بقيت بتكتب الكود بطريقة Testable بالفطرة. ابدأ صغير، استمر، وهتلاقي جودة شغلك اتنقلت لمستوى تاني خالص.
لو عندك أي استفسار أو واجهت مشكلة في PHPUnit أو Pest، سيبلي تعليق ونفكر سوا! بالتوفيق في رحلتك البرمجية.