اختبار PHP: الوحدات والتكامل واختبارات E2E على المستوى المتقدم

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

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

ابدأ الدورة

اختبار PHP: الوحدات والتكامل واختبارات E2E على المستوى المتقدم



في تطوير الويب الحديث باستخدام PHP، لم تعد جودة الكود خيارًا - بل شرطًا أساسيًا لبقاء المشروع. اختبارات الوحدة الأساسية مألوفة لكل مطور، ولكن بمجرد أن يتجاوز المشروع إطار "Hello World"، تظهر الحاجة إلى أساليب أكثر تعقيدًا: اختبارات التكامل، والتحقق من تفاعل المكونات، والاختبار الشامل لسيناريوهات المستخدم (E2E).



هذه المقالة مخصصة لمطوري PHP من المستوى المتوسط فما فوق، الذين هم على دراية بالفعل بـ PHPUnit ويرغبون في تعميق معرفتهم. سنناقش التقنيات المتقدمة: الاختبار مع التبعيات الخارجية، العمل مع حاويات الاختبار، عزل البنية التحتية، وبناء استراتيجية اختبار شاملة.



1. اختبار الوحدات المتقدم: كائنات Mock و Stub



على المستوى المتقدم، لم تعد اختبارات الوحدة مجرد التحقق من الدوال الرياضية. إنها تختبر منطق الأعمال، معزولة عن العالم الخارجي. الأدوات الرئيسية هي Mock و Stub.



Stub يُرجع بيانات محددة مسبقًا. Mock يتحقق من كيفية استدعاء الدوال (عدد الاستدعاءات، ترتيب الوسائط).



لنأخذ مثالاً: خدمة دفع ترسل طلبًا إلى بوابة الدفع.



<?phpclass PaymentService {    public function __construct(        private PaymentGatewayInterface $gateway,        private LoggerInterface $logger    ) {}

public function processPayment(Order $order): bool { $result = $this->gateway->charge( $order->getAmount(), $order->getCurrency() );

if ($result->isSuccess()) { $this->logger->info('Payment processed', ['order_id' => $order->getId()]); return true; }

$this->logger->warning('Payment failed', ['error' => $result->getError()]); return false; }}

// اختبار باستخدام PHPUnitclass PaymentServiceTest extends TestCase { public function testSuccessfulPaymentLogsInfo(): void { // إنشاء Stub للبوابة $gatewayStub = $this->createStub(PaymentGatewayInterface::class); $gatewayStub->method('charge') ->willReturn(new PaymentResult(true));

// إنشاء Mock للمسجل (التحقق من الاستدعاء) $loggerMock = $this->createMock(LoggerInterface::class); $loggerMock->expects($this->once()) ->method('info') ->with('Payment processed', $this->arrayHasKey('order_id'));

$service = new PaymentService($gatewayStub, $loggerMock); $result = $service->processPayment(new Order(100, 'USD'));

$this->assertTrue($result); }}


تقنية متقدمة: استخدم willReturnCallback() للردود الديناميكية و withConsecutive() للتحقق من تسلسل الاستدعاءات.



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



تختبر اختبارات التكامل كيفية تفاعل الكود الخاص بك مع المكونات الحقيقية: قاعدة البيانات، نظام الملفات، ذاكرة التخزين المؤقت. هنا لا يمكن الاعتماد على mock - بل تحتاج إلى بنية تحتية حقيقية.



المشكلة: تصبح الاختبارات بطيئة وهشة. الحل: استخدام حاويات الاختبار (Testcontainers) أو قواعد بيانات SQLite المدمجة.



مثال على اختبار تكامل لمستودع المستخدمين باستخدام Doctrine:



<?phpclass UserRepositoryIntegrationTest extends KernelTestCase {    private EntityManagerInterface $entityManager;    private UserRepository $repository;

protected function setUp(): void { self::bootKernel(); $this->entityManager = self::$kernel->getContainer() ->get('doctrine

المدونات

توصيات الكتب