اختبار PHP: الأطر والأدوات
جودة الكود هي أساس أي مشروع ويب ناجح. بالنسبة لمطوري PHP، لم يعد الاختبار خيارًا بل أصبح مرحلة إلزامية في التطوير. في هذه المقالة، سنستعرض ثلاث أدوات رئيسية: PHPUnit (معيار الصناعة)، Pest (البساطة الحديثة)، وCodeception (الاختبار التكاملي). ستتعلم كيفية كتابة اختبارات الوحدة، والعمل مع كائنات mock، وتطبيق TDD في مشاريع PHP.
1. PHPUnit - أساس اختبار PHP
PHPUnit هو المعيار الفعلي لاختبار الوحدة في PHP. وهو جزء من Symfony و Laravel وأطر العمل الشائعة الأخرى.
التثبيت واختبار أساسي
composer require --dev phpunit/phpunitمثال لاختبار بسيط لفئة الآلة الحاسبة:
// src/Calculator.phpclass Calculator { public function add($a, $b) { return $a + $b; }}
// tests/CalculatorTest.phpuse PHPUnit\\Framework\\TestCase;
class CalculatorTest extends TestCase { public function testAddition() { $calc = new Calculator(); $this->assertEquals(4, $calc->add(2, 2)); }}العمل مع كائنات mock
يوفر PHPUnit آلية مدمجة لإنشاء كائنات وهمية (mock):
public function testUserRepository() { $mockRepo = $this->createMock(UserRepository::class); $mockRepo->method('findById') ->willReturn(new User(1, 'Alice'));
$service = new UserService($mockRepo); $result = $service->getUser(1); $this->assertEquals('Alice', $result->getName());}2. Pest - بناء جملة أنيق للاختبارات
Pest هو غلاف فوق PHPUnit، يقدم بناء جملة أكثر إيجازًا وقابلية للقراءة. مثالي للمشاريع التي تكون فيها سرعة كتابة الاختبارات مهمة.
التثبيت ومثال
composer require --dev pestphp/pestقارن مع PHPUnit: نفس الاختبار في Pest يبدو كالتالي:
// tests/CalculatorTest.phpit('calculates addition', function () { $calc = new Calculator(); expect($calc->add(2, 2))->toBe(4);});إمكانيات متقدمة
- Higher Order Tests - سلاسل استدعاء بدون تداخل
- Architecture Testing - التحقق من بنية الفئات
- Snapshot Testing - المقارنة مع البيانات المرجعية
3. Codeception - للاختبار التكاملي والوظيفي
Codeception يجمع اختبارات الوحدة والوظيفية والقبول في إطار عمل واحد. يدعم Selenium و Symfony و Laravel و Yii وحتى WordPress.
هيكل الاختبارات
codecept generate:cest acceptance LoginCestمثال لاختبار وظيفي لـ Laravel:
// tests/functional/UserCest.phpclass UserCest { public function testLogin(FunctionalTester $I) { $I->amOnPage('/login'); $I->fillField('email', 'user@example.com'); $I->fillField('password', 'secret'); $I->click('Login'); $I->see('Dashboard'); }}4. أدوات إضافية
- Mockery - مكتبة مرنة لكائنات mock (بديل لميزات mock المدمجة في PHPUnit)
- PHPStan / Psalm - تحليل ثابت يكتشف الأخطاء قبل تشغيل الاختبارات
- Infection - اختبار الطفرات: يتحقق من جودة الاختبارات نفسها
- PHP CodeSniffer - التحقق من الامتثال لمعيار PSR-12
5. مثال عملي: TDD لخدمة API
سنقوم بتنفيذ دورة TDD (التطوير القائم على الاختبار) بسيطة لخدمة الطلبات:
الخطوة 1. كتابة الاختبار
// tests/OrderServiceTest.phppublic function testCrea