اختبارات HTTP في Laravel

من موسوعة حسوب

مقدمة

يزوّدك Laravel بـواجهة برمجيّة سلسة للقيام بطلبات HTTP لتطبيقك وتحليل الناتج. على سبيل المثال، القِ نظرة على الاختبار التالي:

<?php

namespace Tests\Feature;

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

class ExampleTest extends TestCase
{
   /**
    * مثال اختبار بسيط.
    *
    * @return void
    */
   public function testBasicTest()
   {
       $response = $this->get('/');
       $response->assertStatus(200);
   }
}

ينشئ التابع get طلب GET للتطبيق، بينما يتأكد التابع assertStatus من أنّ الرد المُعاد يحتوي على رمز حالة HTTP المعطى. إضافةً إلى هذا التأكد البسيط، يحتوي Laravel على مجموعة من توابع التأكيد لفحص المعلومات المتعلقة بالرد، كترويسات الرد (response headers)‎، ومحتوى الرد، وبنية JSON، والمزيد من المعلومات.

تعديل ترويسات الطلب

يمكنك استخدام التابع withHeaders من أجل تعديل ترويسات الطلب قبل إرساله للتطبيق. يمكنك من خلال هذا التابع إضافة أي ترويسة إلى الطلب المرسل.

<?php

class ExampleTest extends TestCase
{
   /**
    * مثال اختبار بسيط.
    *
    * @return void
    */
   public function testBasicExample()
   {
       $response = $this->withHeaders([
           'X-Header' => 'Value',
       ])->json('POST', '/user', ['name' => 'Sally']);

       $response
           ->assertStatus(201)
           ->assertJson([
               'created' => true,
           ]);
   }
}

ملاحظة: تتوقف البرمجيّة الوسيطة CSRF تلقائيًا أثناء تشغيل الاختبارات.

الجلسة والاستيثاق

يزوّدك Laravel بمجموعة من التوابع المساعدة للعمل مع الجلسات أثناء القيام باختبارات HTTP. أولًا، يمكنك تعيين بيانات الجلسة إلى مصفوفة محدّدة وذلك باستخدام التابع withSession؛ إذ يساعد هذا التابع على تحميل الجلسة بالبيانات قبل إرسال الطلب لتطبيقك:

<?php

class ExampleTest extends TestCase
{
   public function testApplication()
   {
       $response = $this->withSession(['foo' => 'bar'])
                        ->get('/');
   }
}

بالطبع، إن أحد أهم استخدامات الجلسة هو الحاجة للاحتفاظ بحالة مستخدم الاستيثاق. يزوّدك التابع المساعد actingAs بطريقة بسيطة لتسجيل الدخول باستخدام المستخدم المعطى. فعلى سبيل المثال، يمكننا استخدام model factory لتوليد المستخدم وتسجيل الدخول باستخدامه:

<?php

use App\User;

class ExampleTest extends TestCase
{
   public function testApplication()
   {
       $user = factory(User::class)->create();

       $response = $this->actingAs($user)
                        ->withSession(['foo' => 'bar'])
                        ->get('/');
   }
}

يمكنك أيضًا تعيين أي حارس (guard) سيتمّ استخدامه للمصادقة على المستخدم، وذلك بتمرير اسم الحارس كوسيط الثاني للتابع actingAs كالتالي:

$this->actingAs($user, 'api')

اختبار الواجهات البرمجيّة JSON

يزوّدك Laravel أيضًا بمجموعة من التوابع المساعدة لاختبار الواجهات البرمجيّة التي تخص JSON وردودها. على سبيل المثال، يمكن استخدام التوابع json و get و post و put و patch و delete لإرسال الطلبات باستخدام طرق HTTP المتعددة. يمكنك أيضًا تمرير البيانات والترويسات بسهولة لهذه التوابع. للبدء، لنكتب اختبار يرسل طلب POST إلى user/ ويتأكّد من أنّ البيانات المتوقّعة توافق البيانات المعادة:

<?php

class ExampleTest extends TestCase
{
   /**
    * مثال اختبار بسيط.
    *
    * @return void
    */
   public function testBasicExample()
   {
       $response = $this->json('POST', '/user', ['name' => 'Sally']);

       $response
           ->assertStatus(201)
           ->assertJson([
               'created' => true,
           ]);
   }
}

ملاحظة: يحوّل التابع assertJson الرد إلى مصفوفة ويستخدم التابع PHPUnit::assertArraySubset للتأكد من أنّ المصفوفة المعطاة موجودة ضمن البيانات المعادة في الرد. لذلك في حال كان هناك بيانات إضافيّة في رد JSON، سيعطي نتيجة إيجابية ما دامت القطعة المعطاة من المصفوفة موجودة في الرد.

التأكّد من موافقة تامّة لرد الـ JSON

في حال أردت التأكّد من أنّ المصفوفة المعطاة توافق تمامًا الرد JSON المعاد من التطبيق، استخدم التابع assertExactJson:

<?php

class ExampleTest extends TestCase
{
   /**
    * مثال اختبار بسيط.
    *
    * @return void
    */
   public function testBasicExample()
   {
       $response = $this->json('POST', '/user', ['name' => 'Sally']);

       $response
           ->assertStatus(201)
           ->assertExactJson([
               'created' => true,
           ]);
   }
}

اختبار رفع الملفات

يزوّد الصنف Illuminate\Http\UploadedFile التابع fake الذي يستخدم لتوليد ملفّات أو صور اختبار. عند دمج هذا التابع المساعد مع التابع fake الخاص بالصنف Storage، يمكن تبسيط رفع الملفات إلى حد كبير. على سبيل المثال، يمكنك دمج هذين التابعين ببساطة لاختبار نموذج رفع صورة شخصية:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
   public function testAvatarUpload()
   {
       Storage::fake('avatars');

       $file = UploadedFile::fake()->image('avatar.jpg');

       $response = $this->json('POST', '/avatar', [
           'avatar' => $file,
       ]);

       // التأكد من تخزين الملف
       Storage::disk('avatars')->assertExists($file->hashName());

       // التأكد من عدم وجود الملف
       Storage::disk('avatars')->assertMissing('missing.jpg');
   }
}

تزييف تخصيص الملفات

عند توليد الملفات باستخدام التابع fake، يمكنك تحديد طول وعرض وحجم الصورة وذلك لاختبار قواعد التحقق الخاصة بتطبيقك:

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

إضافةً إلى إنشاء الصور، يمكنك إنشاء الملفات باختلاف أنواعها باستخدام التابع create كالتالي:

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

التوكيدات المتاحة

توكيدات الردود

يزوّدك Laravel بمجموعة من توابع التوكيد من أجل ملفات الاختبار المكتوبة باستخدام PHPUnit. يمكن استخدام هذه التوكيدات للوصول إلى بيانات الرد المعاد من التوابع المساعدة json و get و post و put و delete:

assertCookie

التأكد من أن الرد يحتوي على ملف تعريف الارتباط cookie المعطى:

$response->assertCookie($cookieName, $value = null);

assertCookieExpired

التأكد من أن الرد يحتوي على ملف تعريف الارتباط cookie المعطى المنتهية صلاحيته:

$response->assertCookieExpired($cookieName);

assertCookieNotExpired

التأكد من أن الرد يحتوي على ملف تعريف الارتباط cookie المعطى غير المنتهية صلاحيته:

$response->assertCookieNotExpired($cookieName);

assertCookieMissing

التأكد من أن الرد لا يحتوي على ملف تعريف الارتباط cookie المعطى:

$response->assertCookieMissing($cookieName);

assertDontSee

التأكد من أن السلسلة النصية المعطاة ليست محتواة ضمن الرد:

$response->assertDontSee($value);

assertDontSeeText

التأكد من أن السلسلة النصية المعطاة ليست محتواة ضمن نص الرد:

$response->assertDontSeeText($value);

assertExactJson

التأكد من أنّ الرد يوافق تمامًا بيانات الـ JSON المعطاة كمصفوفة للتابع:

$response->assertExactJson(array $data);

assertForbidden

التأكد من أن الرد يحتوي على رمز حالة محظور Forbidden status code:

$response->assertForbidden();

assertHeader

التأكد من أن الرد يحتوي على الترويسة المعطاة:

$response->assertHeader($headerName, $value = null);

assertHeaderMissing

التأكد من أن الرد لا يحتوي على الترويسة المعطاة:

$response->assertHeaderMissing($headerName);

assertJson

التأكد من أن الرد يحتوي على بيانات الـ JSON المعطاة كمصفوفة للتابع:

$response->assertJson(array $data);

assertJsonCount

التأكد من أن الرد يحتوي على مصفوفة تملك العدد المعطى من العناصر عند المفتاح key المعطى:

$response->assertJsonCount($count, $key = null);

assertJsonFragment

التأكد من أن الرد يحتوي على قطعة الـ JSON المعطاة:

$response->assertJsonFragment(array $data);

assertJsonMissing

التأكد من أن الرد لا يحتوي على قطعة الـ JSON المعطاة:

$response->assertJsonMissing(array $data);

assertJsonMissingExact

التأكد من أن الرد لا يوافق تمامًا قطعة الـ JSON المعطاة:

$response->assertJsonMissingExact(array $data);

assertJsonStructure

التأكد من أن الرد يحتوي على بنية الـ JSON المعطاة:

$response->assertJsonStructure(array $structure);

assertJsonValidationErrors

التأكد من أن الرد يحتوي على أخطاء الـتحقق المعطاة باستخدام المفاتيح keys:

$response->assertJsonValidationErrors($keys);

assertLocation

التأكد من أن ترويسة Location في الرد تحتوي على الرابط المعطى:

$response->assertLocation($uri);

assertNotFound

التأكد من أن الرد يحتوي على رمز حالة غير الموجود Not found status code:

$response->assertNotFound();

assertOk

التأكد من أن الرد يحتوي على رمز الحالة 200:

$response->assertOk();

assertPlainCookie

التأكد من أن الرد يحتوي على ملف تعريف الارتباط المعطى بشكل غير مشفر:

$response->assertPlainCookie($cookieName, $value = null);

assertRedirect

التأكد من أن الرد هو إعادة توجيه إلى الرابط المعطى:

$response->assertRedirect($uri);

assertSee

التأكد من أن السلسلة النصية المعطاة محتواة ضمن الرد:

$response->assertSee($value);

assertSeeInOrder

التأكد من أن الرد يحتوي على السلاسل النصية المعطاة ضمن الترتيب نفسه:

$response->assertSeeInOrder(array $values);

assertSeeText

التأكد من أن السلسلة النصية المعطاة محتواة ضمن نص الرد:

$response->assertSeeText($value);

assertSeeTextInOrder

التأكد من أن نص الرد يحتوي على السلاسل النصية المعطاة ضمن الترتيب نفسه:

$response->assertSeeTextInOrder(array $values);

assertSessionHas

التأكد من أن الجلسة تحتوي على البيانات المعطاة بمفتاح واحد:

$response->assertSessionHas($key, $value = null);

assertSessionHasAll

التأكد من أن الجلسة تحتوي على مجموعة البيانات المعطاة بعدة مفاتيح:

$response->assertSessionHasAll(array $data);

assertSessionHasErrors

التأكد من أن الجلسة تحتوي على خطأ عند الـ field المحدد:

$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');

assertSessionHasErrorsIn

التأكد من أن الجلسة تحتوي على الأخطاء المعطاة:

$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

assertSessionHasNoErrors

التأكد من أن الجلسة لا تحتوي على أية أخطاء:

$response->assertSessionHasNoErrors();

assertSessionMissing

التأكد من أن الجلسة لا تحتوي على المفتاح المعطى:

$response->assertSessionMissing($key);

assertStatus

التأكد من أن الرد يحتوي على رمز الحالة المعطى:

$response->assertStatus($code);

assertSuccessful

التأكد من أن الرد يحتوي على رمز حالة ناجح 2xx:

$response->assertSuccessful();

assertViewHas

التأكد من أن واجهة الرد response view تحتوي على البيانات المعطاة بمفتاح واحد:

$response->assertViewHas($key, $value = null);

assertViewHasAll

التأكد من أن واجهة الرد response view تحتوي مجموعة على البيانات المعطاة بعدة مفاتيح:

$response->assertViewHasAll(array $data);

assertViewIs

التأكد من أن الواجهة المعطاة توافق الواجهة المعادة:

$response->assertViewIs($value);

assertViewMissing

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

$response->assertViewMissing($key);

توكيدات الاستيثاق

يزوّدك Laravel أيضًا بمجموعة من التوكيدات المتعلقة بالاستيثاق من أجل اختبارات الـ PHPUnit:

التابع الشرح
$this->assertAuthenticated($guard = null);
التأكد من أن المستخدم مصادق عليه.
$this->assertGuest($guard = null);
التأكد من أن المستخدم غير مصادق عليه.
$this->assertAuthenticatedAs($user, $guard = null);
التأكد من أن المستخدم المعطى مصادق عليه.
$this->assertCredentials(array $credentials, $guard = null);
التأكد من أن الثبوتيات المعطاة صحيحة.
$this->assertInvalidCredentials(array $credentials, $guard = null);
التأكد من أن الثبوتيات المعطاة غير صحيحة.

مصادر