اختبار PHP: unit, integration, e2e من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا الاختبار في PHP ليس خيارًا، بل معيارًا

في تطوير PHP الحديث، لم يعد الاختبار مجرد "أسلوب حسن" بل تحول إلى مرحلة إلزامية في مشاريع الإنتاج. بدون تغطية الكود بالاختبارات، فإنك تخاطر بإطلاق خطأ في الإنتاج قد يكلف الشركة المال والسمعة. في هذه المقالة، سنستعرض ثلاثة مستويات من الاختبارات: unit (الاختبارات الوحدوية)، integration (اختبارات التكامل)، و e2e (الاختبارات الشاملة). ستتعرف على الفروق بينها، والأدوات التي يجب استخدامها (PHPUnit, Pest, Laravel Dusk, Codeception)، وكيفية بناء استراتيجية اختبار صحيحة لمشروع PHP الخاص بك.



1. اختبارات Unit: اختبار الوحدات المعزولة من الكود

تختبر اختبارات Unit عمل الفئات أو الدوال أو الطرق الفردية بمعزل عن التبعيات الخارجية (قواعد البيانات، واجهات API، نظام الملفات). هذا هو أسرع وأرخص أنواع الاختبارات. الأداة الرئيسية في PHP هي PHPUnit (المعيار الفعلي) والبديل "الحديث" Pest.



1.1. التثبيت وأول اختبار باستخدام PHPUnit

قم بتثبيت PHPUnit عبر Composer:

composer require --dev phpunit/phpunit

أنشئ اختبارًا لفئة آلة حاسبة بسيطة:

<?php// src/Calculator.phpclass Calculator {    public function add(int $a, int $b): int {        return $a + $b;    }}

// tests/CalculatorTest.phpuse PHPUnit\\Framework\\TestCase;

class CalculatorTest extends TestCase { public function testAddition(): void { $calc = new Calculator(); $result = $calc->add(2, 3); $this->assertEquals(5, $result); }}

قم بتشغيل الاختبار:

./vendor/bin/phpunit tests


1.2. استخدام كائنات Mock

لعزل الفئة التي نختبرها، نقوم "باستبدال" تبعياتها باستخدام mocks. مثال مع مستودع المستخدمين:

<?phpclass UserService {    private UserRepository $repo;    public function __construct(UserRepository $repo) {        $this->repo = $repo;    }    public function getUserName(int $id): string {        $user = $this->repo->findById($id);        return $user ? $user->getName() : 'Guest';    }}

// في الاختبار$mockRepo = $this->createMock(UserRepository::class);$mockRepo->method('findById') ->with(1) ->willReturn(new User('Alice'));

$service = new UserService($mockRepo);$this->assertEquals('Alice', $service->getUserName(1));

Best practice: اكتب اختبارات Unit لكل منطق الأعمال. يجب أن تُنفذ في ثوانٍ وألا تعتمد على البيئة.



2. اختبارات Integration: التحقق من التفاعل مع قواعد البيانات وواجهات API والخدمات الخارجية

تتحقق اختبارات التكامل من كيفية عمل فئاتك مع المكونات الحقيقية: قاعدة البيانات، ذاكرة التخزين المؤقت، خدمات HTTP الخارجية. إنها أبطأ من اختبارات Unit، لكنها تمنح ثقة أكبر في أن النظام يعمل ككل متكامل.



2.1. اختبار العمل مع قاعدة البيانات (Laravel + RefreshDatabase)

إذا كنت تستخدم Laravel، تصبح اختبارات التكامل سهلة جدًا بفضل trait RefreshDatabase:

<?phpnamespace Tests\\Feature;

use Tests\\TestCase;use Illuminate\\Foundation\\Testing\\RefreshDatabase;

class UserRegistrationTest extends TestCase { use RefreshDatabase;

public function test_user_can_register(): void { $response = $this->post('/register', [ 'name' => 'John', 'email' => 'john@example.com', 'password' => 'secret123', ]);

$response->assertStatus(302); // إعادة توجيه بعد النجاح $this->assertDatabaseHas('users', [ 'email' => 'john@example.com' ]); }}

يقوم trait RefreshDatabase تلقائيًا بترحيل قاعدة البيانات قبل الاختبارات و

المدونات

توصيات الكتب