از استارتآپها تا شرکتها، سازمانها بهطور گستردهای از TDD به عنوان یک رویکرد متعادل برای بهینهسازی سه فعالیت استفاده میکنند: کدگذاری، تست و طراحی. قدرت کدنویسی با اطمینان: برنامه لاراول خود را با توسعه تست محور تقویت کنید.
توسعه تست محور (TDD) یک فرآیند توسعه نرم افزار است که در آن ابتدا یک تست خودکار می نویسید که رفتار یک قطعه کوچک از کد را مشخص و تایید می کند، سپس کدی را می نویسید که تست تایید می کند. با TDD، می توانید از یک کد صحیح، قوی و قابل نگهداری اطمینان حاصل کنید. در این مقاله نحوه پیاده سازی TDD در لاراول را بررسی خواهیم کرد.
توسعه تست محور (TDD) چیست؟
توسعه تست محور (Test Driven Development) یک فرآیند توسعه تکراری است. در TDD، توسعه دهندگان قبل از نوشتن کد production کافی برای انجام آن تست و بازسازی بعدی، یک تست می نویسند. توسعه دهندگان از مشخصات استفاده می کنند و ابتدا تستی را می نویسند که توضیح می دهد کد چگونه باید رفتار کند. این یک چرخه سریع از تست، کدگذاری، و refactoring است. برای آشنایی دقیق با TDD می توانید این مقاله را بررسی کنید.
چرا باید از توسعه تست محور استفاده کنیم؟
قابلیت اطمینان کد ارتقا یافته: توسعه دهندگان می توانند اطمینان حاصل کنند که کد آنها عملکرد و رفتار مورد انتظار را برآورده می کند، باگ ها و اشتباهات طراحی را کاهش می دهد و از همان ابتدا چیز درست را به روش درست ایجاد می کند.
بازخورد سریعتر: خطاها را زود تشخیص می دهد، بازخورد فوری ارائه می دهد و بنابراین زمان و تلاش لازم برای رفع آنها را کاهش می دهد.
اصلاحات کد مطمئن تر: مجموعه ای جامع از تست ها اطمینان را در هنگام ایجاد تغییرات یا بازسازی کد فراهم می کند، خطر نقص های جدید را کاهش می دهد و اطمینان می دهد که کد الزامات را برآورده می کند.
بازسازی آسان تر: به شناسایی سریع مسائل و کاهش خطر ایجاد نقص های جدید در طول فرآیند بازسازی، حفظ کیفیت کد و اطمینان از رفتار صحیح کد کمک می کند.
کار گروهی برتر: با تعیین مشخصات واضح و اهداف مشترک، کاهش ابهام و سوء تفاهم و سادهسازی فرآیند توسعه، همکاری و کارایی را در تیمهای توسعه نرمافزار تشویق میکند.
فرایند توسعه تست محور
توسعه تست محور (TDD) یک روش توسعه نرم افزار است.
جریان معمولی این است:
نوشتن موارد تست با شروع از الزامات؛
نوشتن کدی که تست ها را حل می کند.
برای گذراندن تمام تست ها، کد را دوباره refactoring می کنیم.
نوشتن تستها قبل از کد، به توسعهدهنده اجازه میدهد:
تمرکز بر الزامات؛
بررسی کنید که آیا برخی از الزامات وجود ندارد یا دقیق نیست.
روی موارد لبه (پارامتر های خالی، پارامترهای نامعتبر و غیره) تمرکز کنید.
این رویکرد به توسعهدهنده کمک میکند و از آن برای ایجاد «کد بهتر و قابل نگهداریتر» کمک میکند، زیرا توسعهدهنده را مجبور میکند کد/توابع را از ابتدا قابل آزمایش کند:
تقسیم کد به "قطعات" کوچکتر و ساده تر.
طرفداری از رویکرد مسئولیت واحد؛
طرفداری از جداسازی کد (یا کپسوله کردن).
کلمات کمتر و کد بیشتر.
نحوه پیاده سازی TDD در لاراول
در این بخش می خواهیم با هم دیگر TDD را در لاراول پیاده سازی کنیم، برای پیاده سازی توسعه تست محور ما از چارچوب تست PHPUnit در این مقاله استفاده خواهیم کرد، اگر می خواهید با چارچوب تست PestPHP پیاده سازی کنید این مقاله را بررسی کنید.
پیش نیازها:
برای درک مفهوم توسعه تست محور در لاراول، باید درک اولیه ای از موارد زیر داشته باشید:
PHPUnit: یک چارچوب تست واحد برای PHP است. برای نوشتن تست در لاراول استفاده می شود.
PestPHP: یک چارچوب تست واحد برای PHP است. همانند PHPUnit برای نوشتن تست در لاراول استفاده می شود. و در لاراول 11 به عنوان چارچوپ تست پیش فرض استفاده می شود.
برنامه نویسی شی گرا (OOP): داشتن درک اولیه از مفاهیم OOP مانند کلاس ها، اشیاء، وراثت و رابط ها ضروری است. آشنایی با اصول سالید نیز اهمیت دارد.
تست نرم افزار: دانش اساسی در مورد مفاهیم تست نرم افزار مانند تست واحد، تست یکپارچه سازی و تست پذیرش برای درک TDD مهم است.
گام 1. نصب و پیکربندی:
برای پیکربندی Test Driven Development (TDD) در لاراول، باید مراحل زیر را دنبال کنید:
Laravel را نصب کنید: اولین قدم این است که با اجرای دستور زیر در ترمینال خود لاراول را روی دستگاه خود نصب کنید:
composer create-project --prefer-dist laravel/laravel <project-name>
متغیر های environment خود را تنظیم کنید: این مرحله شامل پیکربندی اتصال پایگاه داده و سایر تنظیمات است. می توانید این کار را با کپی کردن فایل env.example.
در env.
و سپس ویرایش تنظیمات در فایل env.
انجام دهید.
PHPUnit را نصب کنید: PHPUnit چارچوب تست واحد برای PHP است که باید برای نوشتن و اجرای تست ها در لاراول نصب شود. با اجرای دستور زیر در ترمینال خود می توانید این کار را انجام دهید:
composer require --dev phpunit/phpunit
گام 2. ایجا تست
برای این کار باید یک فایل PHP جدید در پوشه tests/
ایجاد کنید. نام فایل باید به Test.php
ختم شود. در این فایل باید روش های تستی که رفتار کد شما را توصیف می کند را تعریف کنید.
با دستور زیر می توانید یک تست ایجاد کنید.
php artisan make:test ExampleTest
گام 3. اجرای تست
پس از ایجاد یک تست، می توانید آن را با استفاده از PHPUnit اجرا کنید. برای اجرای تمام تست ها در دایرکتوری tests/
، دستور زیر را در ترمینال خود اجرا کنید:
vendor/bin/phpunit
با این کار تمام تست های موجود در دایرکتوری tests/
اجرا می شود و نتایج را در ترمینال خروجی می دهد. همچنین می توانید با دستور Artisan زیر نیز تست را اجرا کنید :
php artisan test
گام 4. پیاده سازی تست در لاراول
بیایید به یک مثال ساده نگاه کنیم تا نحوه عملکرد TDD در لاراول را نشان دهیم. فرض کنید می خواهیم یک برنامه وبلاگ ساده ایجاد کنیم. ما باید توابعی مانند ایجاد یک وبلاگ جدید، گرفتن یک وبلاگ خاص، به روز رسانی یک وبلاگ موجود و حذف یک وبلاگ داشته باشیم. بنابراین در اینجا، ما یک PostController
داریم.
/**
* PostController
*/
class PostController extends Controller
{
/**
* Function is used to create the blog.
*
* @param Request $request
* @return JsonResponse
*/
public function createBlog(Request $request): JsonResponse
{
$post = Post::create([
'title' => $request->input('title'),
'body' => $request->input('body'),
'user_id' => Auth::id(),
]);
return response()->json($post, 201);
}
/**
* Get the blog information by id.
*
* @param integer $id
* @return JsonResponse
*/
public function getBlogById(int $id): JsonResponse
{
$post = Post::findOrFail($id);
return response()->json($post);
}
/**
* Function is used to update the blog.
*
* @param Request $request
* @param integer $id
* @return JsonResponse
*/
public function updateBlog(Request $request, int $id): JsonResponse
{
$post = Post::findOrFail($id);
$post->update([
'title' => $request->input('title'),
'body' => $request->input('body'),
]);
return response()->json($post);
}
/**
* Function is used to delete the blog.
*
* @param integer $id
* @return void
*/
public function deleteBlog(int $id)
{
$post = Post::findOrFail($id);
$post->delete();
return response()->noContent();
}
}
اکنون، بیایید یک مورد تست برای ایجاد وبلاگ بنویسیم.
class BlogTest extends TestCase
{
/** @test */
public function a_user_can_create_a_blog_post()
{
// Arrange
$user = factory(User::class)->create();
$post = [
'title' => 'My first blog post',
'body' => 'This is the body of my first blog post.',
];
// Act
$response = $this->actingAs($user)->post('/createBlog', $post);
// Assert
$response->assertStatus(201);
$this->assertDatabaseHas('posts', $post);
}
}
در این مثال، ما از کلاس TestCase
داخلی لاراول استفاده میکنیم که مجموعهای از متد ها را برای آسانتر کردن تست ارائه میکند. ما همچنین از کلاس Factory
لاراول برای ایجاد یک کاربر جدید استفاده می کنیم.
متد تست a_user_can_create_a_blog_post
دارای سه بخش Arrange، Act و Assert است.
در بخش Arrange، ما یک کاربر جدید ایجاد می کنیم و داده ها را برای یک پست وبلاگ جدید تعریف می کنیم.
در بخش Act، کاربر را تحریک میکنیم که با دادههای پست وبلاگ جدید، درخواست POST را به نقطه پایانی posts/
ارسال کند.
در بخش Assert، ما بررسی میکنیم که کد وضعیت پاسخ 201 (ایجاد شده) باشد، که نشان میدهد پست وبلاگ با موفقیت ایجاد شده است. ما همچنین مطابقت داریم که دادههای پست وبلاگ جدید در پایگاه داده درج شده است.
بیایید متد GET را برای بازیابی یک پست وبلاگ بنویسیم. در اینجا یک نمونه تست وجود دارد:
class BlogTest extends TestCase
{
public function test_user_can_retrieve_single_blog_post()
{
// Arrange
$post = factory(Post::class)->create();
// Act
$response = $this->get("/getBlogById/{$post->id}");
// Assert
$response->assertStatus(200);
$response->assertJson([
'id' => $post->id,
'title' => $post->title,
'body' => $post->body,
]);
}
}
در اینجا، در این مثال، ما یک پست وبلاگ جدید با استفاده از متد factory
لاراول ایجاد می کنیم، یک درخواست GET به نقطه پایانی posts/{id}/
می دهیم تا پست را بازیابی کند، و سپس بررسی می کنیم که پاسخ دارای کد وضعیت 200 باشد ( OK) و اینکه دادههای JSON پاسخ با دادههای پستی که ایجاد کردیم مطابقت دارد.
حالا بیایید به روش PUT برای به روز رسانی یک پست وبلاگ برویم. در اینجا یک نمونه تست وجود دارد:
class BlogTest extends TestCase
{
public function test_user_can_update_blog_post()
{
// Arrange
$post = factory(Post::class)->create();
$newData = [
'title' => 'New title',
'body' => 'New body',
];
// Act
$response = $this->put("/updateBlog/{$post->id}", $newData);
// Assert
$response->assertStatus(200);
$this->assertDatabaseHas('posts', array_merge(['id' => $post->id], $newData));
}
}
در این مثال، ما یک پست وبلاگ جدید با استفاده از متد factory
لاراول ایجاد میکنیم، دادههای جدیدی را برای بهروزرسانی پست تعریف میکنیم، یک درخواست PUT به نقطه پایانی posts/{id}/
برای بهروزرسانی پست ایجاد میکنیم، و سپس بررسی میکنیم که آیا پاسخ داده میشود. دارای کد وضعیت 200 (OK) و اینکه داده های پست در پایگاه داده به روز شده است.
در مرحله بعد، بیایید به متد DELETE برای حذف یک پست وبلاگ برویم. در اینجا یک نمونه تست وجود دارد:
class BlogTest extends TestCase
{
public function test_user_can_delete_blog_post()
{
// Arrange
$post = factory(Post::class)->create();
// Act
$response = $this->delete("/deleteBlog/{$post->id}");
// Assert
$response->assertStatus(204);
$this->assertDatabaseMissing('posts', ['id' => $post->id]);
}
}
در این مثال، ما یک پست وبلاگ جدید با استفاده از متد factory
لاراول ایجاد می کنیم، یک درخواست DELETE به نقطه پایانی posts/{id}/
می دهیم تا پست را حذف کند، و سپس بررسی می کنیم که پاسخ دارای کد وضعیت 204 باشد (بدون محتوا). و اینکه داده های پست از پایگاه داده حذف شده است.
گام آخر
TDD در لاراول یک فرآیند در حال تکامل است و زمینه های مختلفی وجود دارد که می توان آن را بهبود بخشید یا بیشتر توسعه داد. برخی از مراحل بعدی ممکن برای TDD در لاراول عبارتند از:
تست یکپارچه سازی: تست های ادغام بررسی می کنند که تک تک کدها به درستی با هم کار می کنند، و اطمینان حاصل می کنند که برنامه به طور کلی مطابق انتظار کار می کند و آنها را به یک گردش کار TDD تبدیل می کند.
توسعه مبتنی بر رفتار (BDD): BDD توسعه ای از TDD است که بر رفتار مورد انتظار یک برنامه از دیدگاه کاربر تمرکز می کند. در لاراول، BDD را می توان با استفاده از چارچوب هایی مانند Behat
یا Codeception
پیاده سازی کرد.
ادغام پیوسته (CI) و استقرار پیوسته (CD): CI/CD مجموعه ای از اقدامات است که فرآیند آزمایش، ساخت و استقرار کد را خودکار می کند. ادغام TDD با CI/CD می تواند به اطمینان حاصل شود که کد شما همیشه به درستی آزمایش و اجرا می شود.
تجزیه و تحلیل پوشش تست: تجزیه و تحلیل پوشش تست به شما کمک می کند تا تعیین کنید چه مقدار از کد شما تحت پوشش تست ها است. این می تواند به شما کمک کند مناطقی از کد خود را که نیاز به آزمایش بیشتری دارند شناسایی کنید و از موثر بودن تست های شما اطمینان حاصل کنید.
تزریق ماک و وابستگی: در لاراول، تکنیکهای تزریق ماک و وابستگی، جداسازی بخشهای کد را در حین آزمایش امکانپذیر میکنند و میتوانند با استفاده از کتابخانههایی مانند Mockery
یا توابع ماک داخلی PHPUnit پیادهسازی شوند. برای آشنایی با تزریق وابستگی در لاراول این مقاله را بررسی کنید.
نتیجه
پشتیبانی لاراول از توسعه مبتنی بر تست برای هر توسعهدهندهای که به دنبال ساخت برنامههای کاربردی قابل اعتماد و با کیفیت است، ارزشمند است. با پذیرش TDD، میتوانید نرمافزار بهتری بسازید، باگها را زودتر در فرآیند توسعه پیدا کنید و مطمئن شوید که کدتان قوی و قابل اعتماد است.