Summarize this content to 400 words in Persian Lang
TL;DR: چگونه با شبیه سازی به اکوسیستم لاراول دسترسی پیدا کنیم beforeAll و afterAll روش های آزمایش آفت
نمونه پروژه لاراول را می توان در این مورد یافت مخزن Github. بیشتر بدانید کپسول، X یا بلواسکی.
من به استعاره ای نیاز داشتم تا مقاله خود را نشان دهم و آزمایش آفت را مشخص کنم.
کلود: تست آفت مانند همبرگر است. هسته ی آزمایش، پتی آبدار است: این قسمت اصلی است، بخشی که تمام طعم را به ارمغان می آورد. در اطراف آن، شما باید beforeEach و afterEach عملکردها، که به عنوان تاپینگ و سس عمل می کنند و طعم و زمینه را به هر لقمه اضافه می کنند. در نهایت، beforeAll و afterAll توابع مانند buns هستند: آنها ساختار را ارائه می دهند و همه چیز را در کنار هم نگه می دارند. همه اینها با هم یک تجربه تست کاملا متعادل را ایجاد می کند. به طور خلاصه، نوشتن تست آفت مانند درست کردن یک همبرگر خوب است: همه مواد مهم هستند و این هماهنگی آنهاست که تفاوت را ایجاد می کند.
هوم باشه با تشکر، کلود.
با توجه به مستندات PestPHP، $this متغیر در دسترس نیست beforeAll و afterAll روش های یک آزمون این به این دلیل است که این هوک ها قبل از اجرای هر آزمایشی اجرا می شوند:
beforeAll()
Executes the provided closure once before any tests are run within the current file, allowing you to perform any necessary setup or initialization that applies to all tests.
beforeAll(function () {
// Prepare something once before any of this file’s tests run…
});
It’s important to note that unlike the beforeEach() hook, the $this variable is not available in the beforeAll() hook. This is because the hook runs before any tests are executed, so there is no instance of the test class or object to which the variable could refer.
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
برای درک بهتر این موضوع، توجه به این نکته مهم است که Pest بر روی PHPUnit ساخته شده است. آفت beforeAll و afterAll توابع بر اساس PHPUnit هستند setUp و tearDown روش هایی که در هر آزمون یک بار اجرا می شوند. اما در مورد Pest، این هوک ها فقط یک بار در هر فایل فراخوانی می شوند. این جادوی آفت است. تنها مسئله این است که در طول این تماس ها هیچ چیز در دسترس نیست.
بنابراین دسترسی به آن غیرممکن است $this، برنامه لاراول یا خواص آن در a beforeAll() یا afterAll() قلاب حداقل نه بدون راه حل خاص. این مقاله به بررسی این راه حل می پردازد.
از یک پروژه استاندارد لاراول، PHPUnit را با Pest جایگزین کنید.
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response
Tests: 2 passed (2 assertions)
Duration: 0.21s
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
اگر پروژه از Vite استفاده می کند، a Vite manifest not found ممکن است خطا رخ دهد برای حل این مشکل، Vite باید در قسمت غیرفعال شود setUp روش از TestCase.php فایل
tests/TestCase.php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
protected function setUp() : void
{
parent::setUp();
$this->withoutVite();
}
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
برای اهداف این مقاله، Feature دایرکتوری حذف می شود این Feature سپس مجموعه آزمایشی باید از آن حذف شود phpunit.xml فایل، همراه با خط مربوطه در Pest.php فایل در نهایت، Unit/ExampleTest.php فایل با Unit/BootloadableTest.php.
phpunit.xml
xml version=”1.0″ encoding=”UTF-8″?>
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:noNamespaceSchemaLocation=”vendor/phpunit/phpunit/phpunit.xsd”
bootstrap=”vendor/autoload.php”
colors=”true”
>
name=”Unit”>
tests/Unit
app
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
Pest.php
use Tests\TestCase;
pest()->extend( TestCase::class )->in( ‘Unit’ );
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
Unit/BootloadableTest.php
it( “can say ‘Hello World !'”, function()
{
$message = ‘Hello World !’;
echo “$message\n”;
expect( $message )->toBeString()->toEqual( ‘Hello World !’ );
} );
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
> vendor/bin/pest
Hello World !
PASS Tests\Unit\BootloadableTest
✓ it can say ‘Hello World !’
Tests: 1 passed (2 assertions)
Duration: 0.07s
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
هدف این مقاله به اشتراک گذاشتن داده های یکسان در بین تست ها است که از یک اجرای یک فرمان تولید می شود php artisan migrate –seed.
برای انجام این کار، لازم است کمی تغییر دهید DatabaseSeeder.php فایل برای ایجاد دو User در هر seed.
database/seeders/DatabaseSeeder.php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
public function run() : void
{
User::factory( 2 )->create();
}
}
نتیجه قابل پیش بینی است، همانطور که beforeEachهمانطور که از نامش پیداست، قبل از هر تست اجرا می شود. در این مورد، چرا از آن استفاده نکنید beforeAll به جای قلاب؟
این $this متغیر در دسترس نیست beforeAll عملکرد، و نه نماها. به عنوان مثال، Artisan::call(‘migrate:fresh –seed’) در این زمینه نیز کار نمی کند. جایگزین: استفاده کنید Bootloadable صفت
خصیصه غلبه می کند setUp و tearDown توابع برای اضافه کردن دو روش جدید: initialize و finalize. این initialize روش یک بار اجرا می شود، مانند beforeAll، در حالی که finalize روش نیز یک بار اجرا می شود، مانند afterAll.
tests\Traits\Bootloadable.php
namespace Tests\Traits;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Pest\TestSuite;
این setUp و tearDown روش ها محدود به تماس هستند initialize و finalize. منطق اصلی در آن قرار دارد init روش
این روش تعداد تست ها را فهرست می کند. این initialize روش زمانی فراخوانی می شود که شمارش اولیه 0 باشد، در حالی که متغیر استاتیک را افزایش می دهد $count. این finalize متد زمانی فراخوانی می شود که این تعداد به طول عدد برسد $tests آرایه، مقداردهی اولیه شده توسط init تابع
برای استفاده از initialize روش، باید صفت را به آن اضافه کنید TestCase و روش مربوطه را اجرا کنید.
tests/TestCase.php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Tests\Traits\Bootloadable;
abstract class TestCase extends BaseTestCase
{
use Bootloadable;
این initialize بنابراین روش می تواند جایگزین شود setUp روش در مورد $this->withoutVite، این پیکربندی را می توان مستقیماً به آن اضافه کرد initialize.
فراموش نکنید که قبلی را حذف کنید beforeAll() از BootloadableTest فایل سپس، دویدن vendor/bin/pest دو بار نتیجه زیر را به همراه خواهد داشت: دو مهاجرت و دانه های مختلف برای یک مجموعه آزمایشی.
it( “can verify first user name between two tests”, function()
{
expect( $this->user->name )->toBe( $this->new );
} );
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
vendor/bin/pest
Mrs. Laurine Ebert V > Capsules Codes
PASS Tests\Unit\FirstTest
✓ it can modify first user name between two test files 0.08s
PASS Tests\Unit\SecondTest
✓ it can verify first user name between two test files 0.01s
Tests: 2 passed (2 assertions)
Duration: 0.13s
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
بر خلاف Pest که اجرا می کند beforeAll و afterAll روشهایی در ابتدا و انتهای آزمایشهای یک فایل، در اینجا بر روی یکTestCase اساس به جای فایل. برای اجرای initialize و finalize روشهایی که در ابتدا و انتهای آزمونها برای یک فایل داده شده، کمی تغییر در Trait ضروری است.
tests/Traits/Bootloadable.php
namespace Tests\Traits;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Pest\TestSuite;
نام آزمون در حال اجرا با استفاده از بازیابی می شود debug_backtrace تابع
متغیر self::$tests اکنون یک آرایه انجمنی است، که در آن هر کلید نشان دهنده نام فایل است، و هر مقدار مربوط به تعداد تست هایی است که شامل آن است.
متغیر self::$count یک بار به صفر بازنشانی می شود finalize روش اجرا شده است.
مرحله آخر: اصلاح کنید TestCase فایل این امکان دسترسی به نام فایل موجود در آن را فراهم می کند.
tests/TestCase.php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Tests\Traits\Bootloadable;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
abstract class TestCase extends BaseTestCase
{
use Bootloadable;
PASS Tests\Unit\FirstTest
✓ it can modify first user name between two tests 0.36s
FAIL Tests\Unit\SecondTest
⨯ it can verify first user name between two tests 0.03s
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
FAILED Tests\Unit\SecondTest > it can verify first user name between two tests
Failed asserting that two strings are identical.
-‘Capsules Codes’
+’Tremayne Spinka’
at tests/Unit/SecondTest.php:18
14▕
15▕
16▕ it( “can verify first user name between two tests”, function()
17▕ {
➜ 18▕ expect( $this->user->name )->toBe( $this->new );
19▕ } );
20▕
به نظر می رسد که Brice Fisher تبدیل شده است Tremayne Spinka!
در اینجا یک نمای کلی از نتیجه به دست آمده با تکرار است BootloadableTest را به دو فایل مجزا تبدیل کنید. [ Make sure to replace “Capsules Codes” with “Pest PHP” in the second file ].
> vendor/bin/pest
Ernestine Dietrich III > Capsules Codes
PASS Tests\Unit\FirstTest
✓ it can modify first user name between two test files
✓ it can verify first user name between two test files
Dr. Nya Gusikowski > Pest PHP
PASS Tests\Unit\SecondTest
✓ it can modify first user name between two test files
✓ it can verify first user name between two test files
Tests: 4 passed (4 assertions)
Duration: 0.42s
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
خوشحالم که این کمک کرد.
TL;DR: چگونه با شبیه سازی به اکوسیستم لاراول دسترسی پیدا کنیم beforeAll و afterAll روش های آزمایش آفت
نمونه پروژه لاراول را می توان در این مورد یافت مخزن Github. بیشتر بدانید کپسول، X یا بلواسکی.
من به استعاره ای نیاز داشتم تا مقاله خود را نشان دهم و آزمایش آفت را مشخص کنم.
کلود: تست آفت مانند همبرگر است. هسته ی آزمایش، پتی آبدار است: این قسمت اصلی است، بخشی که تمام طعم را به ارمغان می آورد. در اطراف آن، شما باید beforeEach و afterEach عملکردها، که به عنوان تاپینگ و سس عمل می کنند و طعم و زمینه را به هر لقمه اضافه می کنند. در نهایت، beforeAll و afterAll توابع مانند buns هستند: آنها ساختار را ارائه می دهند و همه چیز را در کنار هم نگه می دارند. همه اینها با هم یک تجربه تست کاملا متعادل را ایجاد می کند. به طور خلاصه، نوشتن تست آفت مانند درست کردن یک همبرگر خوب است: همه مواد مهم هستند و این هماهنگی آنهاست که تفاوت را ایجاد می کند.
هوم باشه با تشکر، کلود.
با توجه به مستندات PestPHP، $this متغیر در دسترس نیست beforeAll و afterAll روش های یک آزمون این به این دلیل است که این هوک ها قبل از اجرای هر آزمایشی اجرا می شوند:
beforeAll()
Executes the provided closure once before any tests are run within the current file, allowing you to perform any necessary setup or initialization that applies to all tests.
beforeAll(function () {
// Prepare something once before any of this file's tests run...
});
It's important to note that unlike the beforeEach() hook, the $this variable is not available in the beforeAll() hook. This is because the hook runs before any tests are executed, so there is no instance of the test class or object to which the variable could refer.
برای درک بهتر این موضوع، توجه به این نکته مهم است که Pest بر روی PHPUnit ساخته شده است. آفت beforeAll و afterAll توابع بر اساس PHPUnit هستند setUp و tearDown روش هایی که در هر آزمون یک بار اجرا می شوند. اما در مورد Pest، این هوک ها فقط یک بار در هر فایل فراخوانی می شوند. این جادوی آفت است. تنها مسئله این است که در طول این تماس ها هیچ چیز در دسترس نیست.
بنابراین دسترسی به آن غیرممکن است $this، برنامه لاراول یا خواص آن در a beforeAll() یا afterAll() قلاب حداقل نه بدون راه حل خاص. این مقاله به بررسی این راه حل می پردازد.
از یک پروژه استاندارد لاراول، PHPUnit را با Pest جایگزین کنید.
> vendor/bin/pest
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response
Tests: 2 passed (2 assertions)
Duration: 0.21s
اگر پروژه از Vite استفاده می کند، a Vite manifest not found ممکن است خطا رخ دهد برای حل این مشکل، Vite باید در قسمت غیرفعال شود setUp روش از TestCase.php فایل
برای اهداف این مقاله، Feature دایرکتوری حذف می شود این Feature سپس مجموعه آزمایشی باید از آن حذف شود phpunit.xml فایل، همراه با خط مربوطه در Pest.php فایل در نهایت، Unit/ExampleTest.php فایل با Unit/BootloadableTest.php.
در شروع دو تست یکسان، با اضافه کردن دستور Artisan در beforeEach() قلاب
tests/Unit/BootloadableTest.php
useApp\Models\User;beforeEach(function(){$this->artisan('migrate:fresh --seed');});it("can dump users for the first time",function(){dump(User::select('name','email')->get()->toArray());});it("can dump users for the second time",function(){dd(User::select('name','email')->get()->toArray());});
نتیجه قابل پیش بینی است، همانطور که beforeEachهمانطور که از نامش پیداست، قبل از هر تست اجرا می شود. در این مورد، چرا از آن استفاده نکنید beforeAll به جای قلاب؟
> vendor/bin/pest
FAIL Tests\Unit\BootloadableTest
─────────────────────────────────────────
FAILED Tests\Unit\BootloadableTest >
Using $this when not in object context
این $this متغیر در دسترس نیست beforeAll عملکرد، و نه نماها. به عنوان مثال، Artisan::call('migrate:fresh --seed') در این زمینه نیز کار نمی کند. جایگزین: استفاده کنید Bootloadable صفت
خصیصه غلبه می کند setUp و tearDown توابع برای اضافه کردن دو روش جدید: initialize و finalize. این initialize روش یک بار اجرا می شود، مانند beforeAll، در حالی که finalize روش نیز یک بار اجرا می شود، مانند afterAll.
این setUp و tearDown روش ها محدود به تماس هستند initialize و finalize. منطق اصلی در آن قرار دارد init روش
این روش تعداد تست ها را فهرست می کند. این initialize روش زمانی فراخوانی می شود که شمارش اولیه 0 باشد، در حالی که متغیر استاتیک را افزایش می دهد $count. این finalize متد زمانی فراخوانی می شود که این تعداد به طول عدد برسد $tests آرایه، مقداردهی اولیه شده توسط init تابع
برای استفاده از initialize روش، باید صفت را به آن اضافه کنید TestCase و روش مربوطه را اجرا کنید.
این initialize بنابراین روش می تواند جایگزین شود setUp روش در مورد $this->withoutVite، این پیکربندی را می توان مستقیماً به آن اضافه کرد initialize.
فراموش نکنید که قبلی را حذف کنید beforeAll() از BootloadableTest فایل سپس، دویدن vendor/bin/pest دو بار نتیجه زیر را به همراه خواهد داشت: دو مهاجرت و دانه های مختلف برای یک مجموعه آزمایشی.
اکنون زمان دستکاری داده ها در آزمون های مختلف است.
بیایید تصور کنیم که تست اول نام کاربر اول را تغییر میدهد و تست دوم نام بهروزرسانیشده از تست اول را تأیید میکند.
Tests/Unit/BootloadableTest.php
useApp\Models\User;beforeEach(function(){$this->user=User::first();$this->new="Capsules Codes";});it("can modify first user name between two tests",function(){$name=$this->user->name;echo$this->user->name;expect($this->user->name)->toBe($name);$this->user->name=$this->new;$this->user->save();});it("can verify first user name between two tests",function(){echo" > {$this->user->name}\n";expect($this->user->name)->toBe($this->new);});
نتیجه پس از دو اعدام متوالی از vendor/bin/pest فرمان
> vendor/bin/pest
Esteban Raynor > Capsules Codes
PASS Tests\Unit\BootloadableTest
✓ it can modify first user name between two tests
✓ it can verify first user name between two tests
Tests: 2 passed (2 assertions)
Duration: 0.40s
> vendor/bin/pest
Demario Corkery > Capsules Codes
PASS Tests\Unit\BootloadableTest
✓ it can modify first user name between two tests
✓ it can verify first user name between two tests
Tests: 2 passed (2 assertions)
Duration: 0.39s
اگر هر تست در فایل خودش قرار گیرد چه اتفاقی می افتد؟
Unit/FirstTest.php
useApp\Models\User;beforeEach(function(){$this->user=User::first();$this->new="Capsules Codes";});it("can modify first user name between two tests",function(){$name=$this->user->name;echo"{$this->user->name} > $this->new\n";expect($this->user->name)->toBe($name);$this->user->name=$this->new;$this->user->save();});
Unit/SecondTest.php
useApp\Models\User;beforeEach(function(){$this->user=User::first();$this->new="Capsules Codes";});it("can verify first user name between two tests",function(){expect($this->user->name)->toBe($this->new);});
بر خلاف Pest که اجرا می کند beforeAll و afterAll روشهایی در ابتدا و انتهای آزمایشهای یک فایل، در اینجا بر روی یکTestCase اساس به جای فایل. برای اجرای initialize و finalize روشهایی که در ابتدا و انتهای آزمونها برای یک فایل داده شده، کمی تغییر در Trait ضروری است.
>vendor/bin/testBriceFisher>CapsulesCodesPASSTests\Unit\FirstTest✓itcanmodifyfirstusernamebetweentwotests0.36sFAILTests\Unit\SecondTest⨯itcanverifyfirstusernamebetweentwotests0.03s─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────FAILEDTests\Unit\SecondTest>itcanverifyfirstusernamebetweentwotestsFailedassertingthattwostringsareidentical.-'Capsules Codes'+'Tremayne Spinka'attests/Unit/SecondTest.php:1814▕15▕16▕it("can verify first user name between two tests",function()17▕{➜18▕expect($this->user->name)->toBe($this->new);19▕});20▕1tests/Unit/SecondTest.php:18Tests:1failed,1passed(2assertions)Duration:0.43s
به نظر می رسد که Brice Fisher تبدیل شده است Tremayne Spinka!
در اینجا یک نمای کلی از نتیجه به دست آمده با تکرار است BootloadableTest را به دو فایل مجزا تبدیل کنید. [ Make sure to replace “Capsules Codes” with “Pest PHP” in the second file ].