تست نویسی در لاراول یکی از گام های مهم در پروژه است و باید با دقت بالا و سرعت بالا انجام گردد. حدود 80 درصد توسعه دهندگان لاراول با تست نویسی مشکل دارند و آن را خیلی سخت و کار بیهوده در نظر می گیرند، در حالی که یکی از جذاب ترین بخش های پروژه تست نویسی است. ما در این مقاله می خواهیم با 9 روش و تکنیک تست نویسی در لاراول آشنا شویم.
مقدمه ای بر تست در لاراول
نوشتن تستهایی برای تضمین سطح ثبات پروژههایی که روی آنها کار میکنید، حرفهتان را سر به فلک میکشد. و این اغراق نیست. تست نویسی همچنین کیفیت زندگی شما را با رهایی از انجام کارهای مشابه در مرورگر وب یا کلاینت HTTP بهبود میبخشد. کامپیوتر شما میتواند در صورت لزوم، تستهایی را که نوشتهاید، صد بار در ساعت اجرا کند. تا زمانی که نوعی سایبورگ آینده نگر نباشید، نمی توانید به این سطح از بهره وری برسید.
اگر اصلاً با تست ها آشنا نیستید، مقاله ای در مورد تست نویسی در لاراول با Pest را بررسی کنید و این که چگونه سریع شروع کنید: در کمتر از 5 دقیقه شروع به تست کد لاراول خود کنید.
بنابراین بله، نوشتن تستهای خودکار میتواند در آغاز زمانی که شما با این فرآیند آشنایی ندارید زمانبر باشد. اما با گذشت زمان تغییر می کند. این ارزش سرمایه گذاری است!
در اینجا یک نمای کلی از تست های با ارزش آورده شده:
چند تست بنویسید تا از پایداری کد خود اطمینان حاصل کنید. زمانی که با آنها آشنا هستید حداکثر یک ساعت بیشتر طول می کشد.
برای تولید مستقر شوید، باگ های جدید را کشف کنید، یک تست شکست خورده بنویسید، کد را اصلاح کنید، تست را قبول کنید و به زندگی خود ادامه دهید. زیرا احتمال کمی وجود دارد که باگی که رفع کرده اید بازگردد.
اکنون، در اینجا یک سناریوی فاجعه معمولی وجود دارد که زمانی اتفاق میافتد که تست ها را ننویسید:
شما مقداری کد می نویسید و دائماً به مرورگر یا کلاینت HTTP خود سوئیچ می کنید تا هر کاری را که انجام می دهید تست کنید و زمان زیادی را در این فرآیند تلف کنید.
شما به مرحله تولید می روید، باگهای زیادی وجود دارد، آنها را به صورت زنده برطرف میکنید، اما برخی از آنها به دلایلی که نمیفهمید بازمیگردند (ما آن را رگرسیون نیز مینامیم)، و در نهایت در یک حلقه نامحدود گیر میکنید. چالش ها و مسائل.
کارفرما یا مشتری شما از دست شما عصبانی است و رابطه تنزل می یابد.
بیایید برای جلوگیری از این امر اقدام کنیم!
بهترین روش های تست برای توسعه دهندگان لاراول
با استفاده از Pest تست بنویسید
Pest مبتنی بر PHPUnit است اما راحتی زیادی به آن اضافه می کند و حتی می تواند کارهایی را انجام دهد که PHPUnit نمی تواند. این چارچوب تستی عالی مجموعه تستی شما را شلوغ می کند زیرا برای عملکرد به کد دیگ بخار کمتری نیاز دارد.
به عنوان مثال، این تست نوشته شده برای PHPUnit را انجام دهید:
<?php
namespace App\Tests\Feature;
use Tests\TestCase;
class SomeFeatureTest extends TestCase
{
public function test_some_feature_works()
{
$this
->get(route('some-route'))
->assertOk()
->assertViewIs('some-view');
}
}
و حالا، تفاوت را با Pest ببینید:
<?php
test('some feature works')
->assertOk()
->assertViewIs('some-view');
Pest دارای ویژگی های فراوانی است. در اینجا چند نمونه از آن آمده است:
ویژگیهای موازی داخلی برای اجرای تستی سریعتر
اسناد زیبا که به راحتی قابل پیمایش است
ابزارهای پروفایل بومی برای بهینه سازی تست های آهسته اجرا
تست معماری خارج از جعبه برای تست قوانین برنامه
گزارش پوشش به طور مستقیم در ترمینال برای پیگیری پوشش کد
ده ها پلاگین اختیاری، مانند حالت تماشا و تست عکس فوری، برای سفارشی کردن Pest مطابق با نیازهای شما.
البته، چه تست خود را با Pest بنویسید چه با PHPUnit، نتیجه اکثراً یکسان خواهد بود. این توصیه برای افرادی است که تازه شروع به کار کرده اند و تا حد ممکن اصطکاک کمتری می خواهند. در لاراول 11 نیز چارچوب تست به صورت پیش فرض Pest است، برای آشنایی با لاراول 11 این مقاله را بررسی کنید.
با استفاده از استک تولید، تست را قابل اعتمادتر کنید
بیایید یک پروژه معمولی لاراول را در نظر بگیریم. آنها معمولا بر روی آخرین نسخه PHP، MySQL و Redis اجرا می شوند. اما احتمالاً تست های خود را با استفاده از SQLite و درایور کش آرایه اجرا می کنید، درست است؟ خب، این اشتباه است، و اجازه دهید توضیح دهم که چرا.
آیا تا به حال به مشکلی با MySQL برخورد کرده اید که SQLite ندارد؟ یا برعکس؟ این به این دلیل است که تست های شما به دلیل تقلید نکردن محیط تست از آنچه در حال تولید است، باگ را پیدا نکردند.
به طور کلی، افراد وابستگیها را جایگزین میکنند تا تستهایشان سریعتر انجام شود. اما به نظر من، یک مجموعه تستی قابل اعتماد در هر زمان می تواند یک مجموعه تستی سریع را شکست دهد. در پایان، شما می خواهید بهترین تجربه کاربری ممکن را به کاربران خود ارائه دهید.
<?xml version="1.0" encoding="UTF-8"?>
<phpunit …>
…
<php>
…
<env name="CACHE_DRIVER" value="redis" /> <!-- [tl! ++] -->
<env name="DB_CONNECTION" value="mysql" /> <!-- [tl! ++] -->
</php>
</phpunit>
برای آشنایی با کد نویسی تمیز در لاراول و جدیدترین تکنیک های لاراول در سال 2024 این مقاله را بررسی کنید.
تست برنامه های وب به تست ویژگی های بیشتری نسبت به تست های واحد نیاز دارد
تست های ویژگی در لاراول برای اطمینان از ثبات کلی یک برنامه وب بسیار ارزشمند است. آنها سفر کاربر را شبیهسازی میکنند و با اجزای فرانت اند و بکاند و همچنین پایگاه داده تعامل دارند و ارزیابی جامعی از برنامه شما ارائه میدهند.
در حالی که اجرای آنها نسبت به تستهای واحد کندتر است، این پوشش جامع اغلب مشکلات ناخواستهای را در مناطقی که حتی هدفش را هم نبودهاید، پیدا میکند. زمان اضافی صرف شده برای اجرای تستهای ویژگی یک مبادله ارزشمند برای سطح بالایی از قابلیت اطمینان آنها در مقایسه با تستهای واحد است. با پیدا کردن مشکلات در کل پایگاه کد شما، آنها به شما این اطمینان را می دهند که برنامه شما همانطور که انتظار می رود در دنیای واقعی کار خواهد کرد.
البته، هیچ چیز کامل نیست، و انواع دیگر تستها باید مانند تست سرتاسری و همچنین بررسیهای دستی توسط انسانها اجرا شوند.
با جعل سرویس از راه دور، تست را سریعتر و ارزان تر کنید
نوشتن تست برای سرویس های راه دور مانند API شخص ثالث یک چالش است. اغلب محدودیتهایی وجود دارد که نمیتوانید به آنها برسید.
بنابراین، تا زمانی که محیط تستی مانند Stripe’s API وجود نداشته باشد، هیچ انتخاب دیگری جز جعل کردن تماسها با API سرویس نخواهید داشت.
لاراول جعلی های زیادی ارائه می دهد تا به ما در شبیه سازی برخی از قسمت های چارچوب کمک کند. در مورد ما، کلاینت HTTP را شبیه سازی می کنیم.
در بخشهایی از کدم، از API OpenAI برای اضافه کردن هوش مصنوعی به پروژه خود استفاده میکنم. در اینجا یک مثال ساده آورده شده است:
use Illuminate\Support\Facades\Http;
Http::withToken(config('services.openai.api_key'))
->post('https://api.openai.com/v1/chat/completions', [
'model' => 'gpt-4',
'messages' => [
[
'role' => 'user',
'content' => 'Some prompt',
],
],
])
->throw()
->json('choices.0.message.content');
اکنون، در اینجا نحوه استفاده از کلاینت جعلی HTTP لاراول برای ذخیره اعتبارات ارزشمند و سرعت بخشیدن به تست هام آمده است:
Http::fake([
'api.openai.com/v1/chat/completions' => Http::response([
'choices' => [[
'message' => ['content' => 'Lorem ipsum dolor sit amet.'],
]],
]),
]);
هر زمان که من این تست را اجرا می کنم، کلاینت HTTP با یک کلاینت جعلی جایگزین می شود که فقط وانمود می کند که API را درخواست می کند و پاسخی را که من کاملاً ساخته ام دریافت می کند.
چگونه بفهمم پاسخ جعلی باید چه باشد؟ فقط هر API را که میخواهید جعل کنید درخواست کنید و خودتان آن را خواهید دید.
آنوفل نیز یک سرویس API رایگان برای تست اپلیکیشن هایتان دارد، کافی است به صورت رایگان ثبت نام کنید و در بخش پنل کاربری به آن دسترسی خواهید داشت.
با Continuous Integration تست را مفیدتر کنید
بهترین راه برای باز کردن پتانسیل کامل تست ها این است که اجازه دهید رایانه دیگری آنها را اجرا کند. به این ادغام پیوسته نیز می گویند. این رایانه آخرین تغییرات را در پایگاه کد شما انجام میدهد، تست هایی را که نوشتهاید اجرا میکند و در صورت عدم موفقیت یکی از آنها به شما اطلاع میدهد.
این کامپیوتر همچنین می تواند یک ماشین مجازی باشد و این ماشین مجازی نیز می تواند توسط یک سرویس شخص ثالث رایگان مانند GitHub Actions ارائه شود. برای آشنایی با گیت هاب اکشن این مقاله را بررسی کنید.
در اینجا نحوه شکلگیری فایل پیکربندی برای یک گردش کاری GitHub Action آمده است. اگر روی پروژه لاراول کار می کنید، می توانید گردش کار زیر را با آن تطبیق دهید. یک فایل در github/workflows/tests.yml
ایجاد کنید و این کد را قرار دهید :
name: Tests
on:
push:
pull_request:
jobs:
tests:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:latest
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
ports:
- 3306
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
coverage: none
php-version: 8.2
- name: Setup the MySQL database
run: mysql -u root -h 127.0.0.1 -P ${{ job.services.mysql.ports[3306] }} -e "CREATE DATABASE laravel"
- name: Setup Redis
uses: zhulik/redis-action@1.1.0
- name: Checkout code
uses: actions/checkout@v3
- name: Create .env file
run: cp .env.example .env
- name: Install back-end dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate encryption key
run: php artisan key:generate
- name: Install and build front-end dependencies
run: yarn && yarn build
- name: Run tests
run: php artisan test
اسناد رسمی لاراول نمونهای از گردش کار GitHub Actions را ارائه میکند تا به شما در اجرای Dusk کمک کند، که میتوانید از آن الهام بگیرید.
اما قبل از رفتن به GitHub برای یادگیری همه چیز در مورد Actions، هنوز یک تمرین وجود دارد که می توانید آن را با یکپارچه سازی مداوم ترکیب کنید تا از سطح توسعه دهنده God فراتر بروید.
با تحویل مداوم، تست را عملی تر کنید
با استفاده از GitHub Actions، دیدیم که چگونه به لطف رایانه دیگری و به صورت رایگان، تست ها را به طور خودکار اجرا کنیم. اما اگر ما قادر به استقرار در محیط تولید خود باشیم، هر زمان که تست ها در برنچ اصلی ما رد شد، چه؟
مرحله زیر را اضافه کنید:
- name: Deploy on production
run: curl -X POST ${{ secrets.DEPLOYMENT_URL }}
if: github.ref == 'refs/heads/main' && success()
ما دستوری را اجرا میکنیم که درخواست POST را به یک URL مخفی میکند (در این مورد، از Ploi برای مدیریت سرور استفاده میکنیم و آنها هوکی را ارائه میدهند که میتوانید برای آن فراخوانی کنید).
این دستور تنها زمانی اجرا می شود که گردش کار موفقیت آمیز باشد. ما همچنین مطمئن می شویم که فقط در شاخه اصلی اتفاق می افتد. (با این پیکربندی، گردش کار در تمام شاخه ها اجرا می شود. در صورت تمایل می توانید آن را سفارشی کنید.)
با نوشتن تست، رفع باگ را تأیید کنید
یک استراتژی محکم برای تست، به ویژه هنگامی که با CI و CD همراه است (ادغام مداوم و استقرار مداوم، نوشتن یک تست برای تأیید رفع اشکال است.
سناریوی فاجعه زیر را تصور کنید:
متوجه شدید که فرم تماس شما در حال بررسی ایمیل فرستنده معتبر نیست.
شما با استفاده از اعتبار سنج لاراول این باگ را برطرف می کنید.
یک روز متوجه شدید که باگ برگشته است زیرا ناخواسته چیزی را تغییر داده اید که بر فرم تماس تأثیر گذاشته است. و بدتر از این؟ شما نمی دانید چه زمانی اتفاق افتاده است.
خوشبختانه، یک راه آسان برای اطمینان از تکرار نشدن این اتفاق وجود دارد: تستی بنویسید که مطمئن شود فرم تماس شما فقط یک آدرس ایمیل فرستنده معتبر را میپذیرد.
it('requires a valid email address', function () {
$this
->post('/contact', [
'email' => 'some-invalid-email-address',
'message' => fake()->paragraph(),
])
->assertInvalid(['email']);
});
اکنون، هر بار که کد را به مخزن Git خود فشار میدهید، محیط CI شما تست ها را اجرا میکند و در صورتی که دادههایی که از فرم تماس شما به دست میآیند آنطور که انتظار میرود تأیید نشده باشند، از استقرار جلوگیری میکند.
با فکر نکردن به آن امتحان را شادتر کنید
هنگامی که با تست خیالتان راحت شد، وسوسه خواهید شد که تمام موارد لبه را پیش بینی کرده اید. در تجربه من، پیش بینی مشکلات واقعی تقریبا غیرممکن است. به کاربران خود اجازه دهید آنها را کشف کنند (این اجتناب ناپذیر است) و یکبار برای همیشه با نوشتن تست هایی برای آنها درست همانطور که قبلاً صحبت کردیم آنها را برطرف کنید.
استراتژی من این است که تست هایی را برای مسیرهای شاد بنویسم (مثلاً «تست فرم تماس همانطور که انتظار می رود کار می کند») و مسیرهای غیر شاد آشکار (مثلاً «تست فرم تماس نیاز به یک آدرس ایمیل معتبر دارد»). خودشه. پس از آن، به کاربران خود اجازه دهید باگ های پیچیده تر را کشف کنند.
همانطور که گفته شد، اکثر اوقات، کاربران شما به شما نمی گویند که چه مشکلی در برنامه های شما وجود دارد و آنها فقط آن را ترک می کنند. بنابراین، اگر میخواهید به طور منفعلانه بازخورد ارزشمندی را جمعآوری کنید، باید از ابزار مناسب استفاده کنید.
ابزارهای نظارت بر خطا مانند Flare یا Sentry می توانند هر زمان که کاربران با خطا مواجه شدند به شما اطلاع دهند. آنها هزاران اطلاعات فنی را ارائه می دهند تا به شما کمک کنند مشخص کنید کدام قسمت از کد شما مقصر است، می توانید مشکلات را به عنوان حل شده علامت گذاری کنید و در صورت رگرسیون اعلان دریافت کنید و موارد دیگر!
همانطور که گفته شد، اگر استراتژی را که در بخش قبل به شما ارائه کردم اعمال کنید، نباید هیچ رگرسیونی دریافت کنید. هر یک از رفع اشکال شما مانند چسب دائمی خواهد ماند.
ورودی ارائه دهید و خروجی را تست کنید
تست ها در مورد ارائه ورودی و تستی است که شما خروجی مورد انتظار را دریافت کنید.
نحوه پیاده سازی کد شما بی ربط است. اگر مشخصات ویژگی تغییر نکند، تست های خوب نیازی به تغییر ندارند.
تصور کنید: شما یک ویژگی دارید که بسته به ورودی، یک تصویر را به صورت پویا تولید می کند. ممکن است تا به حال از GD استفاده کرده باشید، اما زمان آن رسیده است که به Imagick
بروید زیرا از ویژگیای پشتیبانی میکند که GD ندارد یا باگ های کمتری دارد.
برای اطمینان از کارکرد این ویژگی، نباید تست خود را تغییر دهید. در این صورت، من فقط پروژه را به آخرین نسخه اصلی برنامه افزودنی محدود می کنم:
composer require ext-imagick:^3.7
به عنوان یک گام بیشتر می توانید از توسعه تست محور نیر در لاراول استفاده کنید برای آشنایی با آن این مقاله را بررسی کنید.
نتیجه
اگر میخواهید در تست کردن سطح خود را بالا ببرید، نکات بالا را رعایت کنید و بدون هیچ ترسی شروع به تست نویسی کنید، زیرا تست نویسی باعث پیش پینی باگ هایی می شود که ممکن است در نگاه اول کم خطر یا وجود نداشته باشند ولی با یک تغییر ساده به یک باگ پر خطر تبدیل شوند.
اگر درباره تست نویسی در لاراول سوالی دارید یا پیشنهادی حتما در قسمت نظرات آن را با ما به اشتراک بگذارید.