كتابة اختبارات Unit للعلاقات بإطار العمل Laravel

تم نشرها بتاريخ 2019-11-05

متابعةً مقالتي السابقة لماذا اتجهت إلى البرمجة الموجهة للإختبار، أريد كتابة سلسلة من المقالات التي أود فى كل واحدة منها توضيح طريقة اختبار لأجزاء معينة من اﻷكواد، والتي أتمنى أن تكون مجموع مقالات هذه السلسلة توضيح حول طرق كتابة أكواد اﻹختبار التي أقوم بإتباعها والتي أرى أنها تتكرر بالكثير من المشاريع.


أود أن أبدأ بهذه المقالة بالكتابة عن كيفية اختبار أكثر اﻷشياء استخداما وبتأكيد كل منا نقوم باستخدامها بكل مشاريعنا ونقوم بالاعتماد عليها وهي Eloquent Relationships لا يخلو عادةً أي مشروع منها. فقد مر كل منا بمرحلة إنشاء الجداول بشكل مبدئي وربط العلاقات بينها وبعد فترة من العمل والتعديل على الجداول وتغيير أسماء حقولها والتي أحيانا قد تكون هي المفاتيح الثانوية للعلاقات، لنتفاجأ بعدها بظهور أخطاء بالعلاقة وذلك لنسيان أن هذا التغيير تسبب في ظهور خطأ للعلاقة بين الكلاسين، وهنا يأتي دور أهمية اختبار العلاقات التي تقوم بتنبيهك عند حدوث هذا النوع من الأخطاء.


سنقوم بكتابة دوال اختبار Unit Tests لكل من أنواع العلاقات التالية عن طريق الامثلة:

  • One to one and inverse
  • One To Many and inverse
  • Many to many and Inverse

أولا علاقة one to one:

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


نبدأ أولا بكتابة دالة اﻹختبار بكلاس Unit Test الخاص بالمستخدم، لإنشائه نقوم بتنفيذ اﻷمر التالي:


 Php artisan make:test UserTest --unit

سنقوم اﻷن بكتابة دالة اﻷختبار داخل هذا الكلاس


class UserTest extends TestCase
{
   use RefreshDatabase;

   /**
    * @test
    */
   public function it_has_one_phone_number()
   {
       $user = factory('App\User')->create();
       $phoneNumber = factory('App\PhoneNumber')->create(['user_id' => $user->id]);

       $this->assertInstanceOf(PhoneNumber::class, $user->phoneNumber);
   }
}


لقد قمنا بتحديد عنوان الدالة توضح أنه لكل مستخدم لديه رقم هاتف واحد، ثم قمنا بإنشاء مستخدم جديد عن طريق factory  وإنشاء رقم هاتف جديد وربطه بهذا المستخدم، إذا فعندها نتأكد من أنه رقم الهاتف التابع لهذا المستخدم يجب أن يكون من كلاس PhoneNumber ويجب أن تساوي قيمته رقم الهاتف الذي قمنا بتكوينه.


واﻷن سنقوم باختبار العلاقة العكسية لهذه، حيث أنه كل رقم هاتف هو ملك لمستخدم كالتالي:



class PhoneNumberTest extends TestCase
{
   use RefreshDatabase;

   /**
    *@test
    */
   public function it_belongs_to_a_user()
   {
       $phoneNumber = factory('App\PhoneNumber')->create();

       $this->assertInstanceOf(User::class, $phoneNumber->user);
   }
}

نقوم بإنشاء رقم هاتف جديد عن طريق factories والذي تلقائيا سيكون مستخدم جديد لرقم الهاتف هذا.


$factory->define(PhoneNumber::class, function (Faker $faker) {
   return [
       'phone_number' => $faker->phoneNumber,
       'user_id' => factory('App\User')
   ];
});



علاقة one to many

لنفترض أننا سنقوم بإنشاء تطبيق يمكن فيه للمستخدم أن يملك عدة مستندات، وكل مستند يملكه مستخدم واحد إذا ستكون العلاقة كالتالي:

User has many Document

Document belongs to User

 لنقم أولا بكتابة الاختبار بأن لكل مستخدم عدة مستندات


/**
    *@test
    */
   public function it_has_many_documents()
   {
       $user = factory('App\User')->create();
       $documents = factory('App\Document', 2)->create(['user_id' => $user->id]);

       $this->assertInstanceOf(Document::class, $user->documents->first());
       $this->assertCount(2, $user->documents);
   }



بدالة الاختبار نقوم بإنشاء مستخدم جديد ومن ثم مستندين جديدين ونقوم بتعيين أن المفتاح الثانوي وهو المسؤول على العلاقة user_id هو نفسه المستخدم الذي قمنا بإنشاءه، لنتأكد بعدها أنه من المستندات التي يملكها المستخدم $user->documents لو أخذنا أول مستند منها يجب أن يكون من نوع Document Model، وأيضاً نتأكد من أن عدد المستندات التي يملكها المستخدم هي 2.


ولاختبار العلاقة العكسية وهي أن كل مستند يملكه مستخدم واحد وستكون طريقتها مطابقة لطريقة إختبار التي استخدمتها عندما يكون كل رقم هاتف يملكه مستخدم واحد.



class DocumentTest extends TestCase
{
   use RefreshDatabase;

   /**
    *@test
    */
   public function it_belongs_to_a_user()
   {
       $user = factory('App\User')->create();
       $document = factory('App\Document')->create(['user_id' => $user->id]);

       $this->assertInstanceOf(User::class, $document->user);
   }
}

قمنا بإنشاء مستخدم ومستند جديدين وتعيين هذا المستند للمستخدم عن طريق المفتاح الثانوي ومن ثم قمنا بالتأكد من أن المستخدم الذي يملك هذا المستند هو من نوع User model.


علاقة many to many

لنقوم بإختبار هذه العلاقة سنفترض أنه لدينا تطبيق يمكن للمستخدم به أن يكون لديه عدة صلاحيات، وكل صلاحية يمكن أن تنتمي لأكثر من مستخدم

User has many Permission

Permission belongs to many User


نقوم أولا بكتابة الاختبار بأنه يمكن لكل مستخدم أن يكون لديه عدة صلاحيات.



/**
    *@test
    */
   public function it_belogs_to_many_permissions()
   {
       $user = factory('App\User')->create();
       $permission = factory('App\Permission')->create();

       $user->permissions()->attach($permission);

       $this->assertInstanceOf(Permission::class, $user->permissions->first());
       $this->assertCount(1, $user->permissions);
   }


قمنا أولا بإنشاء مستخدم وصلاحية جديدين، وقمنا بإضافة هذه الصلاحية صلاحيات المستخدم عن طريق دالة attach (التي ستقوم بإضافة صف جديد لجدول pivot) ونقوم بعدها بالتحقق من أن الصلاحية اﻷولى التي يملكها المستخدم يجب أن تكون من نوع Permission Model  ونتأكد من أن عدد صلاحيات المستخدم هو 1 وذلك لأننا فقط قمنا يتكون وإضافة صلاحية واحدة له.


وﻷن نقوم بإختبار العلاقة العكسية، وهي أن كل صلاحية يمكن أن تنتمي لأكثر من مستخدم



class PermissionTest extends TestCase
{
   use RefreshDatabase;

   /**
    *@test
    */
   public function it_belongs_to_many_users()
   {
       $user = factory('App\User')->create();
       $permission = factory('App\Permission')->create();

       $permission->users()->attach($user);

       $this->assertInstanceOf(User::class, $permission->users->first());
       $this->assertCount(1, $permission->users);
   }
}


ماقمنا به هو مشابه للسابق، أنشأنا مستخدم وصلاحية وقمنا بإضافة المستخدم لعلاقة المستخدمين الذين يتبعون لهذه الصلاحية، وقمنا بعدها بالتأكد من أن أول مستخدم من مستخدمين الذين يتبعون هذه الصلاحية هو من نوع User Model، وأيضا قمنا بالتحقق من أن عدد المستخدمين لهذه الصلاحية هو مستخدم واحد فقط وذلك لإننا قمنا بإنشاء وإضافة مستخدم واحد لهذه الصلاحية.


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


خولة الشح

تمت كتابتها بواسطة خولة الشح