البرمجة

اختبار تطبيقات Laravel باستخدام PHPUnit

كيف تستخدم PHPUnit لاختبار تطبيقات Laravel

يُعد اختبار البرمجيات أحد الركائز الأساسية لضمان جودة واستقرار التطبيقات البرمجية، لا سيما في بيئات التطوير الحديثة مثل Laravel، التي تعتمد بشكل كبير على الأتمتة لضمان تدفق العمل بسلاسة. ومن الأدوات الأكثر استخدامًا في بيئة PHP لاختبار التطبيقات، تأتي PHPUnit كمعيار راسخ في اختبارات الوحدة (Unit Testing) والاختبارات التكاملية (Integration Testing). في هذا المقال، سنتناول بشكل مفصل كيفية استخدام PHPUnit لاختبار تطبيقات Laravel، موضحين الخطوات، الأدوات، وأفضل الممارسات التي تساعد المطورين على كتابة اختبارات فعالة وشاملة.


مقدمة عن PHPUnit و Laravel

PHPUnit

PHPUnit هو إطار اختبار (Testing Framework) مصمم خصيصًا للغة PHP، يُستخدم لكتابة اختبارات الوحدة التي تهدف إلى التحقق من صحة أداء وحدات صغيرة من الكود (مثل الوظائف والدوال والفئات) بشكل مستقل عن بقية أجزاء التطبيق. يتميز PHPUnit بكونه مفتوح المصدر وواسع الانتشار، ويعتمد عليه في مجتمعات PHP بشكل واسع لضمان جودة البرمجيات.

Laravel وبيئة الاختبار

Laravel هو إطار عمل PHP حديث وقوي لبناء تطبيقات الويب، ويحتوي على بنية متكاملة تدعم الاختبار كجزء من دورة تطوير البرمجيات. يدمج Laravel PHPUnit بشكل افتراضي، مما يُمكن المطورين من كتابة اختباراتهم بسهولة باستخدام الأدوات التي يوفرها Laravel، مثل عمليات إعداد قاعدة البيانات المؤقتة، محاكاة HTTP، والاختبارات التكاملية.


لماذا يجب استخدام PHPUnit مع Laravel؟

  • تحسين جودة البرمجيات: يضمن اختبار كل جزء من التطبيق عمله بشكل صحيح.

  • تسهيل الصيانة: يجعل من السهل التعرف على الأخطاء بعد إضافة أي تغييرات.

  • توثيق سلوك التطبيق: الاختبارات تشكل توثيقًا حيًا لكيفية عمل الوظائف المختلفة.

  • زيادة ثقة المطور: تأكيد أن التعديلات لا تؤثر سلبًا على وظائف التطبيق.


المتطلبات الأساسية لاستخدام PHPUnit في Laravel

قبل البدء، يجب التأكد من توافر البيئة المناسبة:

  • تثبيت PHP (يفضل الإصدار 7.4 أو أعلى)

  • تثبيت Composer لإدارة الحزم

  • مشروع Laravel مُهيأ وجاهز للاختبار (أي يحتوي على ملفات التكوين الأساسية)

  • وجود PHPUnit مثبت ضمن حزم المشروع، والذي يتم عادةً تثبيته تلقائيًا عند إنشاء مشروع Laravel جديد عبر Composer.


إعداد PHPUnit في مشروع Laravel

عند إنشاء مشروع Laravel جديد، يتم تضمين PHPUnit في ملف composer.json ضمن قسم require-dev، وعادةً ما يكون الإصدار متوافقًا مع إطار العمل. للتحقق من وجود PHPUnit:

bash
composer show phpunit/phpunit

وفي حال عدم وجوده يمكن تثبيته عبر الأمر:

bash
composer require --dev phpunit/phpunit

ملف إعداد PHPUnit

يوجد ملف إعداد رئيسي لاختبارات PHPUnit داخل المشروع وهو phpunit.xml في جذر المشروع. يحتوي هذا الملف على إعدادات عامة مثل:

  • مسار مجلد الاختبارات.

  • إعدادات قاعدة البيانات الخاصة بالاختبارات.

  • الإضافات والخيارات الخاصة بتشغيل PHPUnit.

يُمكن تعديل هذا الملف ليتناسب مع متطلبات المشروع أو بيئة الاختبار.


هيكلية مجلد الاختبارات في Laravel

بشكل افتراضي، يحتوي مشروع Laravel على مجلد tests في جذر المشروع، مقسم إلى:

  • Feature: لاختبارات الميزات والوظائف التي تتضمن تفاعلًا بين عدة وحدات.

  • Unit: لاختبارات الوحدة التي تختبر مكونات صغيرة من التطبيق بشكل مستقل.

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


كتابة أول اختبار وحدة باستخدام PHPUnit في Laravel

إنشاء اختبار جديد

يمكن إنشاء اختبار وحدة جديد عبر الأمر التالي:

bash
php artisan make:test ExampleTest --unit

هذا الأمر يُنشئ ملف اختبار جديد داخل مجلد tests/Unit يحمل الاسم ExampleTest.php.

كتابة كود الاختبار

فتح ملف الاختبار وكتابة الكود كالتالي:

php
namespace Tests\Unit; use PHPUnit\Framework\TestCase; class ExampleTest extends TestCase { public function test_basic_assertion() { $this->assertTrue(true); } }

هنا يتم اختبار بسيط باستخدام الدالة assertTrue للتحقق من أن القيمة true صحيحة.


استخدام اختبارات Feature في Laravel

اختبارات Feature تُستخدم لاختبار الوظائف التي تشمل عدة أجزاء من التطبيق مثل التفاعل مع قواعد البيانات، الاستدعاءات HTTP، ونماذج البيانات.

لإنشاء اختبار Feature:

bash
php artisan make:test UserLoginTest

سيتم إنشاء ملف داخل مجلد tests/Feature.

مثال على اختبار Feature لتسجيل الدخول

php
namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use App\Models\User; class UserLoginTest extends TestCase { use RefreshDatabase; public function test_user_can_login_with_valid_credentials() { $user = User::factory()->create([ 'email' => '[email protected]', 'password' => bcrypt('password123'), ]); $response = $this->post('/login', [ 'email' => '[email protected]', 'password' => 'password123', ]); $response->assertRedirect('/home'); $this->assertAuthenticatedAs($user); } }

في هذا الاختبار يتم:

  • استخدام قاعدة بيانات مؤقتة يتم تنظيفها بعد كل اختبار (باستخدام RefreshDatabase).

  • إنشاء مستخدم باستخدام factory.

  • محاكاة طلب POST على مسار تسجيل الدخول.

  • التحقق من إعادة التوجيه للصفحة الرئيسية.

  • التأكد من أن المستخدم تم توثيقه (تم تسجيل دخوله).


أهم أدوات وأساليب PHPUnit في Laravel

1. Assertions (التحققات)

PHPUnit يوفر مجموعة كبيرة من الدوال للتحقق من نتائج الاختبار:

دالة الوصف
assertTrue() التحقق من أن القيمة صحيحة (true)
assertFalse() التحقق من أن القيمة خاطئة (false)
assertEquals() التحقق من مساواة القيمتين
assertNull() التحقق من أن القيمة تساوي null
assertCount() التحقق من عدد العناصر في مجموعة
assertDatabaseHas() التحقق من وجود بيانات في قاعدة البيانات (Laravel)

2. Traits مفيدة

  • RefreshDatabase: يعيد تهيئة قاعدة البيانات بين كل اختبار وآخر.

  • WithoutMiddleware: تعطيل الـ Middleware لتسهيل اختبار بعض الوظائف.

  • WithFaker: توليد بيانات مزيفة لاستخدامها في الاختبارات.

3. محاكاة HTTP Requests

Laravel يوفر طرق محاكاة طلبات HTTP مثل:

  • $this->get($uri) لمحاكاة طلب GET

  • $this->post($uri, $data) لمحاكاة طلب POST

  • $this->put($uri, $data) لمحاكاة طلب PUT

  • $this->delete($uri) لمحاكاة طلب DELETE

4. محاكاة الأحداث (Events) والوظائف (Jobs)

يمكن تعطيل أو محاكاة الأحداث باستخدام:

php
\Event::fake(); \Event::assertDispatched(EventName::class);

اختبار قواعد البيانات في Laravel باستخدام PHPUnit

في المشاريع التي تعتمد على قواعد بيانات، يعد اختبار عمليات الحفظ، التعديل، والحذف أمرًا أساسيًا.

إعداد بيئة الاختبار لقواعد البيانات

يمكن إعداد قاعدة بيانات منفصلة للاختبارات في ملف .env.testing، والذي يتم استدعاؤه عند تشغيل الاختبارات:

env
DB_CONNECTION=sqlite DB_DATABASE=:memory:

تستخدم قاعدة بيانات SQLite في الذاكرة لتسريع عمليات الاختبار وتجنب التأثير على قاعدة البيانات الحقيقية.

مثال على اختبار قاعدة بيانات

php
public function test_user_creation() { $user = User::factory()->create([ 'name' => 'Ahmed', 'email' => '[email protected]', ]); $this->assertDatabaseHas('users', [ 'email' => '[email protected]', ]); }

هنا يتم التحقق من أن السجل الذي تم إنشاؤه موجود في جدول المستخدمين.


تنفيذ الاختبارات وتشغيلها

لتشغيل كافة الاختبارات في مشروع Laravel، يتم استخدام الأمر:

bash
php artisan test

أو

bash
vendor/bin/phpunit

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


تحسين تجربة الاختبار في Laravel

1. تقسيم الاختبارات

يُنصح بتنظيم الاختبارات حسب الوظائف أو الوحدات، حتى يسهل صيانتها وتحديثها.

2. استخدام Factories

استخدام المصانع (Factories) لتوليد بيانات اختبارية أمر مهم لتجنب الاعتماد على بيانات ثابتة، مما يعزز من مرونة الاختبارات.

3. محاكاة الخدمات الخارجية

للتطبيقات التي تعتمد على خدمات خارجية (مثل APIs)، من الأفضل استخدام المحاكاة (Mocking) لتجنب الطلبات الخارجية أثناء الاختبار.


الجدول التالي يلخص بعض الأوامر الأساسية والأدوات المستخدمة في اختبار Laravel مع PHPUnit:

الأمر / الأداة الوصف الاستخدام
php artisan make:test إنشاء ملف اختبار جديد php artisan make:test ExampleTest
php artisan test تشغيل جميع الاختبارات php artisan test
RefreshDatabase trait إعادة تهيئة قاعدة البيانات بين الاختبارات استخدام داخل اختبار لتحديث القاعدة
assertDatabaseHas التحقق من وجود سجل في قاعدة البيانات $this->assertDatabaseHas('table', [...])
$this->post(), $this->get() محاكاة طلبات HTTP $this->post('/login', [...])
\Event::fake() تعطيل الأحداث خلال الاختبار لمحاكاة أو تجاهل الأحداث

خاتمة

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


المراجع