با Laravel و Vue یک برنامه وب مدرن بسازید - قسمت 3: تست API endpoint های برنامه

در مقاله آموزش لاراول قبلی، نحوه ساخت RESTful API Endpoint ها را بررسی کردیم. مورد بعدی که ما در نظر خواهیم گرفت این است که چگونه Endpoint های برنامه را قبل از release تست کنیم. و بسیار مفید است زیرا اطمینان حاصل می کند که در طول عمر برنامه، می توانید از عملکرد API مطابق انتظار مطمئن باشید.

پیش نیازها

این قسمت از آموزش مستلزم داشتن موارد زیر است:

  • Postman بر روی ماشین شما نصب شده باشد.
  • مقاله آموزشی سری 2 این مجموعه را کامل کرده باشید.

وقتی شرایط بالا را آماده کردید، ادامه دهید.

استفاده از Postman برای تست endpoint ها

برای تست API endpoint، قصد داریم از postman استفاده کنیم. Postman یک زنجیره ابزار کامل برای API developer ها است و در همه سیستم عامل های دسک تاپ موجود است.

دانلود و نصب

پس از دانلود postman، آن را نصب کنید. پس از اینکه Postman را با موفقیت بارگیری و نصب کردید، آن را اجرا کنید و باید رابط کاربری زیر را دریافت کنید.

Postman Screenshot

اکنون که Postman با موفقیت نصب شده است، می توانیم درخواست های خود  را به API ارسال کنیم. بیایید با ایجاد یک درخواست GET برای واکشی resource ها از سرور API شروع کنیم.

ما مثالهایی را برای چند endpoint نشان می دهیم و می توانید بقیه موارد را برای سایر endpoint ها تکرار کنید.

برای همه request هایی که با استفاده از postman ارسال شده است، به یاد داشته باشید که برای اطمینان از اینکه پاسخ درستی از API خود دریافت کرده ایم، عنوان هدر Accept: application/json را در تب headers پستمن تنظیم کنید.

 postman به شما کمک می کند تا تمام request های خود را سازماندهی و ذخیره کنید. با این کار بازگشت به درخواست موجود بدون نیاز به تایپ مجدد آسان تر می شود.

واکشی resource ها در Postman

برای واکشی resourse ها، باید متد HTTP، معمولاً GET و URL را برای واکشی resourse از آن ارائه دهید. در مورد این برنامه، ما یک endpoint ساده را تست خواهیم کرد.

سرور Laravel خود را استارت کنید، اگر از قبل فعال نیست، با استفاده از دستور php artisan serve:

از آنجا که ما یک authorization middleware به route ها اضافه کرده ایم، فراخوانی این endpoint ها بدون احراز هویت دارای پاسخ ناموفق  "“401 Unauthorized" خواهد بود. نحوه درخواستهای مجاز را بعداً در این مقاله بررسی خواهیم کرد.

URL: http://127.0.0.1:8000/api/category/
Method: GET

Postman Screenshot

ایجاد resource ها  با استفاده از Postman

برای ایجاد resource ها، شما باید متد HTTP، معمولاً POST و URL را برای ارسال داده های ایجاد شده نیز ارائه دهید. در مورد این برنامه، ما یک endpoint ساده را تست خواهیم کرد.

سرور Laravel خود را استارت کنید، اگر از قبل فعال نیست، با استفاده از دستور php artisan serve:

URL: http://127.0.0.1:8000/api/category
Method: POST
Body: name

Postman Screenshot

آپدیت resource ها  با استفاده از Postman

برای آپدیت یک resource، باید متد HTTP، معمولاً PUT (یا بسته به ترجیح شما، PATCH) و URL برای ارسال داده، ارائه کنید. در مورد این برنامه، ما یک endpoint ساده را تست خواهیم کرد.

سرور Laravel خود را استارت کنید، اگر از قبل فعال نیست، با استفاده از دستور php artisan serve:

URL: http://127.0.0.1:8000/api/category/{category_id}
Method: PUT
Body: name

Postman Screenshot

حذف resource ها با استفاده از Postman

برای حذف یک resource، باید متد HTTP، معمولاً DELETE، و URL منبع مورد حذف را ارائه دهید. در مورد این برنامه، ما یک endpoint ساده را تست خواهیم کرد.

سرور Laravel خود را استارت کنید، اگر از قبل فعال نیست، با استفاده از دستور php artisan serve:

URL: http://127.0.0.1:8000/api/category/{category_id}
Method: DELETE

Postman Screenshot

ایجاد درخواست های مجاز با استفاده از access token ها

بخشهای خاصی از برنامه ما فقط توسط کاربران معتبر قابل دسترسی است. برای این منظور، در مقاله قبلی، چند مورد endpoint برای authentication اضافه کردیم. هنگامی که کاربر به این endpoint ها برخورد می کند، احراز هویت می شود و یک access token به او ارائه می شود. پیوستن این access token به ریکوئست در مسیر محافظت شده به کاربر امکان دسترسی به resource را می دهد.

برای ایجاد توکن در backend برای API، از Laravel Passport که قبلاً تنظیم کرده ایم استفاده خواهیم کرد. اکنون نحوه استفاده از access token های خود با Postman را بررسی خواهیم کرد. اول از همه، شما باید token را با لاگین کاربر دریافت کنید. اگر کاربر اکانت ندارد، ما یک اکانت ایجاد می کنیم و سپس وارد سیستم می شویم.

ایجاد اکانت کاربری جدید

برای ایجاد کاربر جدید، همانطور که در تصویر زیر نشان داده شده است، با استفاده از Postman درخواست را POST کنید:

URL: http://127.0.0.1:8000/api/register
Method: POST
Body: name, email, password

Postman Screenshot

همانطور که از پاسخ بالا مشخص است، token یی وجود دارد که با response برمی گردد. کلاینت می تواند با استفاده از token به دست آمده از API به عنوان access_token ریکوئست بیشتر ارسال کند.

شما باید این token را برای استفاده در سایر API endpoint ها به جز/api/login endpoint کپی کنید.

ورود به حساب کاربری

برای ورود به یک حساب کاربری، همانطور که در تصویر زیر مشاهده می کنید، با استفاده از Postman درخواستی را به endpoint ارسال کنید:

URL: http://127.0.0.1:8000/api/login
Method: POST
Body: email, password

Postman Screenshot

استفاده از access token ها  برای تایید اعتبار درخواست ها

اکنون که توکن را از درخواستهای قبلی بدست آوردیم، مورد بعدی این است که با استفاده از access token ها درخواست بعدی خود را ارسال کنیم.پس ریکوئست خود را برای واکشی همه category ها ارسال می کنیم.

قبل از انجام این کار، فایل  CategoryController.php را باز کنید و متد index را به صورت زیر آپدیت کنید:

    [...]

    public function index()
    {
        return response()->json(Category::all()->toArray());
    }

    [...]

اکنون می توانیم درخواست خود را در Postman ارسال کنیم.

درخواست بدون تعیین حالت احراز هویت و توکن fail خواهد بود. برای احراز هویت درخواست، به تب Authorization بروید و سپس توکن به دست آمده از آخرین درخواست login/register را وارد کنید.

URL: http://127.0.0.1:8000/api/category
Method: GET

Postman Screenshot

همانطور که از تصویر بالا مشاهده می شود، category ها در بخش response نمایش داده می شوند. اگر token را حذف یا تغییر دهید و درخواست جدیدی ارسال کنید، پاسخ "Unauthorised" دریافت خواهید کرد.

ایجاد اتوماتیک access token ها برای درخواست های Postman

حالا که می دانیم چگونه از access token ها برای ارسال درخواست با Postman استفاده کنیم و متوجه شدیم که فرآیند manual است. از آنجا که می توانیم با استفاده از Postman ریکوئست های زیادی را ارسال کنیم، از postman می خواهیم تا به طور اتومات access token های ما را ایجاد کند.

برای شروع، باید یک Postman environment ایجاد کنیم. در environment، ما قصد داریم برخی از متغیرها را ایجاد کنیم. برای ایجاد یک environment جدید، روی دکمه Environment quick look در بالا سمت راست کلیک کنید و سپس نام environment را که می خواهید ایجاد کنید وارد کنید.

Postman Screenshot

بعد، environment variable ها را اضافه کنید. ما یک متغیر برای url و همچنین یک token ایجاد خواهیم کرد.

ما مقدار مربوط به فیلد token را خالی خواهیم گذاشت زیرا این همان چیزی است که می خواهیم تولید کنیم، بنابراین نیازی به تعیین value نداریم.

Postman Screenshot

environment جدید خود را ذخیره کنید. بعد ، در سمت راست بالای پنل که معمولاً url در آن وارد می شود، باید environment را از No Environment به نام محیطی که می خواهید استفاده کنید تغییر دهید. در این مثال، Trello Clone.

Postman Screenshot

بیایید ریکوئست login را که قبلاً ارسال کرده بودیم اصلاح کنیم. اکنون در تب Tests، کد زیر را اضافه کنید:

    postman.setEnvironmentVariable("token",  JSON.parse(responseBody).success.token);

کاری که این اسکریپت انجام می دهد این است که توکن را از response دریافت می کند و سپس مقدار را به token environment variable تنظیم می کند. کمی غیر عادی است اما مسئله کپی کردن دستی داده ها را حل می کند.

Postman Screenshot

 

پس از انجام این کار، درخواست را به login endpoint ارسال کنید. بعد، به هر endpoint که به access token نیاز دارد بروید و {{token}} را به تب Authorization اضافه کنید. پس از آن، token به طور خودکار در آنجا اضافه می شود و برای درخواست های دیگر نیازی به کپی کردن رمز دسترسی ندارید.

Postman Screenshot

 unit test برای endpoint ها

احتمالاً تاکنون درباره Test Driven Development و نوشتن تست برای برنامه خود شنیده اید. برخی از توسعه دهندگان از نوشتن تست طفره می روند اما تست نوشتن روش خوبی برای اطمینان از این است که می توانید بدون نگرانی در مورد معرفی باگ ها، کد خود را با اطمینان آپدیت کنید.

unit test ها چه هستند؟

در برنامه نویسی، unit test یک متد تست نرم افزار است که توسط آن unit های جداگانه سورس کد، مجموعه ی یک یا چند ماژول برنامه، usage procedure ها و operating procedure ها تست می شوند تا مشخص شود که آیا برای استفاده مناسب هستند یا خیر.

نوشتن unit test در Laravel

بیایید نگاهی به نحوه نوشتن unit test ها بیندازیم. می خواهیم تست هایی را برای برنامه Trello Clone بنویسیم. 100٪ پوشش نمی خواهیم داشته باشیم، فقط چند مورد است که به شما نشان می دهد چگونه می توانید تست های خود را بنویسید.

laravel همراه با برخی از starter code برای یونیت تست ساخته شده است. برای انجام یک تست جدید در لاراول، دستور زیر را اجرا می کنید:

    $ php artisan make:test APITest --unit

تست رجیستر کاربر جدید

بیایید تستی بنویسیم تا بررسی کند که آیا register endpoint شما کار می کند یا خیر. فایل APITest.php را در دایرکتوری tests/Unit باز کرده و کد زیر را در فایل قرار دهید:

    json('POST', '/api/register', [
                'name' => 'Demo User',
                'email' => str_random(10) . '@demo.com',
                'password' => '12345',
            ]);

            $response->assertStatus(200)->assertJsonStructure([
                'success' => ['token', 'name']
            ]);
        }
    }

در کد بالا، ما با استفاده از متد json که با کلاس TestCase  لاراول همراه است، یک درخواست ساختگی ایجاد کردیم و سپس response را بررسی کردیم تا ببینیم کد وضعیت 200 است و آیا ساختار برگشتی با انتظار ما مطابقت دارد یا خیر.

تست logging یک کاربر جدید

برای تست اینکه آیا login endpoint کار می کند، یک متد جدید به کلاس APITest اضافه کنیم:

    public function testUserLogin()
    {
        $response = $this->json('POST', '/api/login', [
            'email' => 'demo@demo.com',
            'password' => 'secret'
        ]);

        $response->assertStatus(200)->assertJsonStructure([
            'success' => ['token']
        ]);
    }

تست واکشی همه category ها

برای تست واکشی category ها. متد زیر را به کلاس اضافه کنید:

    public function testCategoryFetch()
    {
        $user = \App\User::find(1);

        $response = $this->actingAs($user, 'api')
            ->json('GET', '/api/category')
            ->assertStatus(200)->assertJsonStructure([
                '*' => [
                    'id',
                    'name',
                    'created_at',
                    'updated_at',
                    'deleted_at'
                ]
            ]
        );
    }

ساختار فوق با علامت * نشان داده می شود که key می تواند هر string باشد.

از آنجا که ما لاجیکی برای برخی از متد ها در category controller خود نداریم، بیایید برخی را اضافه کنیم. در قسمت های بعدی آن را آپدیت می کنیم. فایل CategoryController را باز کرده و متد های زیر را آپدیت کنید همانطور که مشاهده می کنید:

    public function store(Request $request)
    {
        return response()->json(['status' => true, 'message' => 'Category Created']);
    }

    public function destroy(Category $category)
    {
        return response()->json(['status' => true, 'message' => 'Category Deleted']);
    }

حالا بیایید این endpoint ها را تست کنیم.

تست ایجاد یک category resource جدید

برای تست افزودن category جدید، متد زیر را به کلاس APITest اضافه کنید:

    public function testCategoryCreation()
    {
        $this->withoutMiddleware();

        $response = $this->json('POST', '/api/category', [
            'name' => str_random(10),
        ]);

        $response->assertStatus(200)->assertJson([
            'status' => true,
            'message' => 'Category Created'
        ]);
    }

در بالا، $this->withoutMiddleware() را فراخوانی می کنیم. که middleware های ثبت شده در این endpoint را کنار می گذارد. از آنجا که auth:api یک middleware ثبت شده در این endpoint است، نادیده گرفته می شود و می توانیم بدون authentication فراخوانی کنیم. این یک متد توصیه شده نیست اما خوب است بدانید که وجود دارد.

تست حذف یک category resource

بیایید یک تست برای حذف resource بنویسیم. در test class، متد زیر را اضافه کنید:

    public function testCategoryDeletion()
    {
        $user = \App\User::find(1);

        $category = \App\Category::create(['name' => 'To be deleted']);

        $response = $this->actingAs($user, 'api')
            ->json('DELETE', "/api/category/{$category->id}")
            ->assertStatus(200)->assertJson([
                'status' => true,
                'message' => 'Category Deleted'
            ]);
    }

اجرای unit test ها

اکنون که تست های خود را نوشتید، می توانید آنها را با استفاده از دستور زیر در روت پروژه خود اجرا کنید:

    $ ./vendor/bin/phpunit

Unit tests run

از خروجی بالا، می توانید ببینید که همه تست ها موفق بوده است و بهتر این است که به نوشتن تست های بیشتر ادامه دهیم.

استفاده از یک دیتابیس جداگانه برای unit test ها

نکته مهم، هنگام اجرای تست ها، قطعاً می خواهیم از یک دیتابیس متفاوت از DB فعلی خود استفاده کنیم تا بهم ریخته نشود. لاراول به ما کمک می کند تا به طور موثر این مسئله را مدیریت کنیم.

اگر می خواهید این کار را در پروژه دیگری که با آن کار می کنید انجام دهید، فایل phpunit.xml را در روت پروژه خود باز کنید و به دنبال tag بگردید. فرزندان این tag را با موارد زیر جایگزین کنید:

    [...]
    
    
    
    
    
    
     
    [...]

این PHPUnit را مجبور می کند از SQLite در حافظه به عنوان دیتابیس خود استفاده کند. سپس، در test class، موارد زیر را اضافه کنید:

    <‌?php

    [...]
    use Illuminate\Foundation\Testing\DatabaseMigrations;

    class SomeTest extends TestCase
    {
        use DatabaseMigrations;

        [...]
    }

    [...]

لازم نیست این کار را در تست های پروژه فعلی انجام دهید ، زیرا پروژه برای آن تنظیم نشده است. این فقط خوب است که بدانید.

ویژگی DatabaseMigrations قبل از اجرای تست باعث می شود که یک migration اجرا شود. این اطمینان می دهد که جداول قبل از اجرای تست ها وجود دارند بنابراین خطاهای دیتابیس دریافت نمی کنیم.

نتیجه

در این مقاله از آموزشهای لاراول، نحوه استفاده از Postman برای تست API endpoint را مشاهده کرده ایم. ما همچنین فرایند تولید token را برای درخواست ها به صورت خودکار انجام دادیم. ما همچنین مشاهده کردیم که چگونه با unit test ها API Endpoint ها را تست کنیم.

× در حال پاسخ به: