"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > نصائح لاختبار الوظائف في قائمة الانتظار في Laravel

نصائح لاختبار الوظائف في قائمة الانتظار في Laravel

تم النشر بتاريخ 2024-11-05
تصفح:132

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

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

/* ImportUsersCommand.php */

namespace App\Console\Commands;

/*...*/

class ImportUsersCommand extends Command
{
    protected $signature = 'app:import-users';

    public function handle()
    {
        dispatch(new ImportUsersJob());

        $this->line('Users imported successfully.');
        $this->line('There are: ' . User::count(). ' Users.');
    }
}

في هذا المثال، يرسل الأمر مهمة للتعامل مع قراءة الملف وإنشاء المستخدمين. إليك الشكل الذي قد يبدو عليه ملف ImportUsersJob.php:

/* ImportUsersJob.php */

namespace App\Jobs;

/*...*/

class ImportUsersJob implements ShouldQueue
{
    public function handle(FileReader $reader): void
    {   
        foreach($reader->read('users.csv') as $data) {
            User::create([
                'name' => $data['name'], 
                'email' => $data['email'],
            ]);
        }
    }
}

عند اختبار هذه الميزة، قد يبدو الاختبار النموذجي للأمر كما يلي:

/* ImportUsersCommandTest.php */

namespace Tests\Feature;

/*...*/

class ImportUsersCommandTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_processes_the_file(): void
    {
        Storage::fake('local')->put('users.csv', "...");

        $this->artisan('app:import-users')
            ->expectsOutput('Users imported successfully.')
            ->expectsOutput('There are: 10 Users.')
            ->assertSuccessful();

        $this->assertDatabaseCount('users', 10);
    }
}

للوهلة الأولى، يبدو أن هذا الاختبار يعمل بشكل مثالي. يُظهر تشغيل مجموعة الاختبار نتيجة ناجحة:

Tips for testing queued jobs in Laravel

تنفيذ العالم الحقيقي

ومع ذلك، عند تشغيل الأمر app:import-users في بيئة حقيقية، قد تحصل على نتيجة غير متوقعة:

Tips for testing queued jobs in Laravel

كما ترون، يشير إخراج الأمر إلى وجود 0 مستخدم في قاعدة البيانات. فلماذا يحدث هذا؟

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

لماذا ينجح الاختبار؟

تستخدم مجموعة الاختبار برنامج تشغيل قائمة انتظار المزامنة بشكل افتراضي، مما يعني أنه تتم معالجة المهام بشكل متزامن أثناء الاختبار. ونتيجة لذلك، يتم تنفيذ المهمة على الفور، مما يعطي فكرة أن كل شيء يعمل كما هو متوقع.

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

بمجرد أن تدرك هذا التمييز، قد ترغب في تحسين اختباراتك لتجنب "الإيجابيات الكاذبة".

تم إرسال اختبار وظيفتك

أولاً، من المهم التحقق من أن الأمر يرسل المهمة فعليًا، بغض النظر عما إذا كانت المهمة تتم معالجتها بشكل متزامن أو غير متزامن. إليك كيفية اختبار ذلك:

/* ImportUsersCommandTest.php */

namespace Tests\Feature;

/*...*/

class ImportUsersCommandTest extends TestCase
{    
    public function test_it_dispatches_the_job(): void
    {
        Queue:fake();

        $this->artisan('app:import-users')
            ->expectsOutput('Process has been queued.')
            ->assertSuccessful();

        Queue::assertPushed(ImportUsersJob::class);
    }
}

تتم معالجة اختبار وظيفتك

بمجرد التأكد من إرسال الوظيفة، يمكنك اختبار العمل الفعلي الذي تؤديه الوظيفة في اختبار منفصل. إليك كيفية تنظيم اختبار الوظيفة:

/* ImportUsersJobTest.php */

namespace Tests\Feature;

/*...*/

class ImportUsersJobTest extends TestCase
{
    use refreshDatabase;

    public function test_it_processes_the_file()
    {
        Storage::fake('local')->put('users.csv', "...");

        app()->call([new ImportUsersJob(), 'handle']);

        $this->assertDatabaseCount('users', 10);
    }
}

يضمن هذا أن الوظيفة تؤدي العمل اللازم، بغض النظر عما إذا كانت تتم معالجتها بواسطة قائمة انتظار أو بشكل متزامن.

التعامل مع حالات الحافة

كما هو الحال في الحياة الواقعية، قد تحدث حالات طارئة ويجب أن تكون مستعدًا لها.

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

إذن ماذا يحدث إذا كان الملف غير موجود؟ تحتاج إلى التعامل مع حالات الحافة هذه من خلال التحقق من صحة المدخلات ورمي الاستثناءات عند الضرورة.

إليك كيفية التعامل مع هذا الأمر في وظيفتك:

/* ImportUsersJobTest.php */

namespace App\Jobs;

/*...*/

class ImportUsersJob implements ShouldQueue
{
    use Queueable;

    public function handle(FileReader $reader): void
    {   
        if(!Storage::disk('local')->exists('users.csv')){
            throw new Exception('The users.csv file doesn\'t exist.')
        }

        foreach($reader->read('users.csv') as $data) {
            User::create([
                'name' => $data['name'], 
                'email' => $data['email'],
            ]);
        }
    }
}

إليك كيفية اختبار هذا السيناريو:

/* ImportUsersJobTest.php */

namespace Tests\Feature;

/*...*/

class ImportUsersJobTest extends TestCase
{
    use refreshDatabase;

    /*...*/

    public function test_it_fails_when_file_doesnt_exist(): void
    {
        Storage::fake('local');

        $this->expectException(Exception::class);
        $this->expectExceptionMessage('The users.csv file doesn\'t exist.');

        dispatch(new ImportUsersJob());
    }
}

الأفكار النهائية

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

يسعدني أن أسمع أفكارك!

بيان الافراج تم نشر هذه المقالة على: https://dev.to/eduarguz/tips-for-testing-queued-jobs-in-laravel-4c77?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3