🧪 درس پنجم: تستنویسی حرفهای (TDD)؛ تضمین کیفیت کد با PHPUnit
🎯 هدف این درس: آشنایی با مفهوم تستنویسی خودکار (Automated Testing)، یادگیری فریمورک استاندارد PHPUnit و پیادهسازی اصول اولیه Test-Driven Development (TDD) برای ساخت نرمافزارهای بدون باگ و قابل اعتماد.
مهمان عزیز! 👋
تا اینجا یاد گرفتی کدهای تمیز، ماژولار و استانداردی بنویسی. اما یک سوال مهم باقی میماند: چگونه مطمئن شوی که کدت واقعاً کار میکند و با تغییرات آینده خراب نمیشود؟
در پروژههای بزرگ، تغییر دادن یک خط کد ممکن است باعث خرابی بخشهای دیگری شود که اصلاً به آنها فکر نکردهای. راه حل حرفهای، نوشتن Unit Test است. تستهایی که قطعات کوچک کد تو را به صورت جداگانه بررسی میکنند.
💡 چرا تستنویسی حیاتی است؟
۱. اطمینان از صحت کد: قبل از انتشار، از عملکرد تمام بخشها مطمئن میشوی.
۲. جلوگیری از Regression: وقتی کد جدید اضافه میکنی، تستها مطمئن میشوند کدهای قبلی خراب نشدهاند.
۳. مستندات زنده: تستها نشان میدهند که هر تابع قرار است دقیقاً چه کاری انجام دهد.
1️⃣ نصب و راهاندازی PHPUnit
برای شروع، باید PHPUnit را از طریق Composer نصب کنی. این ابزار استاندارد جهانی برای تست در PHP است.
Terminal
Bash
5.0
composer require --dev phpunit/phpunit ^10.0
سپس یک فایل پیکربندی به نام phpunit.xml در ریشه پروژه بساز تا PHPUnit بداند تستها کجا قرار دارند.
phpunit.xml
XML
1.0
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="Application Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
2️⃣ نوشتن اولین تست (Unit Test)
فرض کن یک کلاس ساده Calculator داری. برای تست متد جمع، یک کلاس تست در پوشه tests میسازیم. نام کلاس تست باید با Test تمام شود.
CalculatorTest.php
PHP
8.x
<?php
use PHPUnit\Framework\TestCase;
use App\Utils\Calculator;
class CalculatorTest extends TestCase {
public function testAddition() {
$calc = new Calculator();
// بررسی میکنیم که ۲ + ۲ برابر با ۴ باشد
$this->assertEquals(4, $calc->add(2, 2));
}
public function testDivisionByZero {
$calc = new Calculator();
// بررسی میکنیم که تقسیم بر صفر استثنا پرتاب کند
$this->expectException(\InvalidArgumentException::class);
$calc->divide(10, 0);
}
}
3️⃣ اجرای تستها
حالا کافیست در ترمینال دستور زیر را اجرا کنی. اگر همه چیز سبز شد، یعنی کدت سالم است!
Terminal
Bash
5.0
./vendor/bin/phpunit
❌ خطاهای رایج در تستنویسی
🚫 اشتباه رایج:
نوشتن تستهایی که به دیتابیس واقعی یا API خارجی وصل هستند. Unit Test باید ایزوله باشد و فقط منطق داخلی کلاس را تست کند. برای موارد خارجی از Mocking استفاده کن.
- تست کردن جزئیات پیادهسازی: تست باید رفتار (Behavior) را چک کند، نه اینکه کد داخلی چگونه نوشته شده است.
- وابستگی تستها به هم: ترتیب اجرای تستها نباید مهم باشد. هر تست باید مستقل اجرا شود.
🏁 جمعبندی درس پنجم
مهمان عزیز، در این درس یاد گرفتی:
- ✅ اهمیت تستنویسی خودکار در پروژههای حرفهای.
- ✅ نحوه نصب و پیکربندی PHPUnit با Composer.
- ✅ نوشتن اولین Unit Test با استفاده از Assertها.
- ✅ نحوه اجرای تستها و تحلیل خروجی.
🎓 تمرین عملی درس پنجم
برای کلاس User که در درسهای قبل ساختی، یک تست بنویس که بررسی کند آیا متد setEmail ایمیلهای نامعتبر را رد میکند یا خیر.
🗺️ نقشه راه دوره: شما اینجا هستید!
برای اینکه بدانی دقیقاً کجای مسیر هستی و چه درسهایی در انتظار توست، به جدول زیر نگاه کن. درس فعلی با رنگ متفاوت مشخص شده است.
| درس | عنوان درس | آنچه یاد میگیرید |
|---|---|---|
| ۱ | اصول SOLID در PHP | تکمسئولیتی، باز/بسته، جایگزینی لیسکوف، جداسازی رابط، وارونگی وابستگی |
| ۲ | الگوهای طراحی (Design Patterns) | Singleton, Factory, Strategy, Observer, MVC پیشرفته |
| ۳ | برنامهنویسی تابعی در PHP | توابع ناشناس (Closures)، Arrow Functions، Map/Filter/Reduce |
| ۴ | مدیریت وابستگی با Composer | نصب پکیجها، مدیریت نسخهها، Autoloading (PSR-4) |
| ۵ | تستنویسی حرفهای (TDD) | آشنایی با PHPUnit، نوشتن Unit Test، Mocking |
| ۶ | کار با Redis و Caching | کش کردن دادهها، Session Handler با Redis |
| ۷ | پردازشهای پسزمینه (Queue & Jobs) | استفاده از صفها برای ایمیلزنی یا پردازش سنگین |
| ۸ | API نویسی حرفهای (RESTful) | استانداردهای REST، احراز هویت با JWT، Rate Limiting |
| ۹ | امنیت سایبری پیشرفته | تحلیل حملات پیچیده، Secure Headers، CSP |
| ۱۰ | پروژه نهایی پیشرفته | ساخت یک CMS ماژولار با قابلیت نصب پلاگین و تم |



