استخدام
معمل النماذج (Model factory) في
Laravel لتوليد بيانات الاختبار
بذر جدول البيانات
نبدأ بفتح الملف database/factories/ModelFactory.php. يأتي الملف مبدئيا بدالّة لـبذر جدول المستخدمين:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
لاحظ
استخدام مكتبة Faker عبر المتغيّر faker$. يجب تنفيذ التهجيرات المبدئية التي تأتي مع
Laravel لإنشاء الجداول في قاعدة البيانات حتى يمكن إدراج تسجيلات فيها.
سنعلّق الدّالة السابقة ونضيف دالة جديدة على النحو التالي:
$factory->define(App\Widget::class, function ($faker) {
return [
'widget_name' => $faker->unique()->word,
];
});
تستدعي الشفرة السابقة مكتبة faker$
لتوليد كلمة word لإدراجها في حقل widget_name، نطلُب من المكتبة التأكد أن الكلمة وحيدة uniq لنوافق القيد الموجود على حقل الاسم في الجدول.
بقيت لنا خطوة قبل بذر الجدول باستخدام أمر artisan. ننتقل إلى المجلّد database/seeds، نفتح الملف DatabaseSeeder.php ونعدّله ليصبح كالتالي:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use App\Widget;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
Widget::truncate();
factory(Widget::class, 50)->create();
Model::reguard();
}
}
تعمل دالة unguard على تعطيل الحماية مؤقّتا على النموذج لحين إدراج التسجيلات، بينما تعيد دالة reguard تفعيلها. تعمل الدّالة truncate على حذف جميع التسجيلات في الجدول لتهيئة عمليّة البذر. نطلُب داخل دالة factory إدراج 50 تسجيلة في جدول النموذج المذكور Widget.
نحن الآن جاهزون لتنفيذ أمر البذر:
php artisan db:seed
الأمر سهل للغاية. يمكنك إن أردت التراجع بنفس السهولة عن الأمر وحذف التسجيلات المدرجة بتنفيذ الأمر:
php artisan migrate:rollback
الطريقة الثانية:
استخدام الاختبارات
توجد طريقة أخرى غير السابقة لإدراج
بيانات وهميّة في جدول بيانات. إن لم تكن لديك فكرة عن التّطوير الموجَّه بالاختبارات Test-driven development, TDD فيمكنك أخذ فكرة عن الأساسيات في مقال كيف تستخدم PHPUnit لاختبار تطبيقات Laravel. سيكون من الجيّد لك التعوّد على
استخدام الاختبارات في أعمال التطوير، خصوصا أن
Laravel يسهّل الأمر كثيرا.
نبدأ بالانتقال إلى ملفّ tests/ExampleTest.php ثم ننشئ نسخة منه باسم WidgetTest.php ونعدّلها لتصبح على النحو التالي:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions ;
use App\Widget;
class WidgetTest extends TestCase
{
use DatabaseTransactions;
/**
* A basic functional test example.
*
* @return void
*/
public function testWidgetFactory()
{
$widgets = factory(Widget::class, 50)->create();
dd($widgets);
}
}
أنشأنا دالة اختبار تستدعي دالة المعمل لإدراج تسجيلات الجدول. بما أننا نستخدم:
use DatabaseTransactions;
فإن التسجيلات لن تبقى مخزّنة في قاعدة البيانات أكثر من حاجة الاختبار.
يؤدي
استخدام الدالة dd إلى طباعة محتوى
النماذج في الطرفيّة عند نجاح الاختبار:
dd($widgets);
سنحتاج قبل تنفيذ
الاختبار إلى حذف محتوى الجدول الناتج عن الطريقة الأولى، لذا ننفذ أمر إرجاع التهجير:
php artisan migrate:rollback
ثم نعيد تنفيذ التهجير لإنشاء الجدول من جديد:
php artisan migrate
نحن الآن جاهزون لتنفيذ الاختبار:
vendor/bin/phpunit tests/WidgetTest.php
أو إن كان مسار PHPUnit مختلفا كما ذكرنا في درس كيف تستخدم PHPUnit لاختبار تطبيقات Laravel:
vendor/phpunit/phpunit/phpunit tests/WidgetTest.php
إن كنت ترغب في إبقاء
بيانات الاختبار في الجدول فيمكنك تعليق
استخدام الصنف التالي:
// use DatabaseTransactions;
يمكن أن تظهر أخطاء عند إعادة تنفيذ
الاختبار بعد إبقاء
بيانات الاختبار السابق في جدول البيانات. يعود السبب في ذلك إلى أن مكتبة Faker لا تعرف مالذي يوجد في جدول البيانات وبالتالي يمكن أن تولّد
بيانات لا تحترم شرط عدم التكرار في محتوى الحقل widget_name. توجد خيارات عدّة لتجاوز هذا الأمر، إما بإرجاع التهجير لحذف الجدول ثم تنفيذ التهجير مرة أخرى لإنشاء الجدول من جديد وبعدها ينفَّذ الاختبار؛ أو
استخدام دالة truncate لحذف التسجيلات من الجدول قبل توليد تسجيلات جديدة. في كلتا الحالتين تُفقَد البيانات السابقة على تنفيذ الاختبار.