- Add 10 core testing guides (setup, AAA principles, PHPUnit/Pest, mocking, anti-patterns, PHP 8.4+, debugging, data factories, advanced edge cases) - Add 13 component testing guides covering all Laravel layers - Add standard templates for PHPUnit 10/11 and Pest v2/v3 including ArchitectureTest - Add Docker smart test runner, dependency installer, and CI/CD templates (GitHub Actions, GitLab CI) - Add 4 Claude Code skills (laravel-test-setup, laravel-unit-test with --all mode, laravel-test-review, laravel-mock-helper) - Add single unified installer script (sg-install-unit-testing.sh) with global support, CLI runners, and 1-click updater (sg-test-update) - Add comprehensive documentation (README.md, USAGE-GUIDE.md) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7.2 KiB
00. Environment & Setup Guide for Laravel Unit Testing
Hướng dẫn thiết lập và chuẩn hóa môi trường kiểm thử (Testing Environment) cho mọi dự án Laravel (Laravel 9, 10, 11).
1. Yêu cầu Thư viện & Dependencies (Composer)
Trước khi viết bất kỳ file Unit Test nào, dự án cần có đầy đủ các thư viện kiểm thử cần thiết trong require-dev.
A. Kiểm tra phiên bản Laravel & Test Framework
Xác định phiên bản Laravel trong composer.json:
- Laravel 9 (PHP 8.0 - 8.1): Thường đi kèm
phpunit/phpunit: ^9.5. - Laravel 10 (PHP 8.1 - 8.2): Hỗ trợ
phpunit/phpunit: ^10.0hoặcpestphp/pest: ^2.0. - Laravel 11 (PHP 8.2 - 8.3+): Mặc định
pestphp/pest: ^2.0|^3.0hoặcphpunit/phpunit: ^10.5|^11.0.
B. Cài đặt các gói cốt lõi (Core Dev Packages)
Nếu dự án dùng PHPUnit:
composer require --dev phpunit/phpunit mockery/mockery fakerphp/faker --with-all-dependencies
Nếu dự án dùng Pest PHP:
composer require --dev pestphp/pest pestphp/pest-plugin-laravel mockery/mockery fakerphp/faker --with-all-dependencies
Các gói bổ trợ tăng tốc & chẩn đoán (Recommended):
- Chạy song song (Parallel Testing):
composer require --dev brianium/paratest # Laravel 9+ có sẵn lệnh: php artisan test --parallel - Làm đẹp output CLI:
composer require --dev nunomaduro/collision
2. Cấu hình Môi trường Test (phpunit.xml & .env.testing)
Một trong những sai lầm nghiêm trọng nhất là để test chạy vào Database dev/staging. Cần cấu hình cách ly tuyệt đối.
A. Tối ưu hóa phpunit.xml (hoặc phpunit.xml.dist)
Đảm bảo thẻ <php> chứa các cấu hình sau:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<php>
<!-- Môi trường test -->
<env name="APP_ENV" value="testing"/>
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
<!-- Tăng tốc mã hóa mật khẩu trong lúc test (từ 10-12 vòng xuống 4 vòng) -->
<env name="BCRYPT_ROUNDS" value="4"/>
<!-- Tắt cache, session, queue, mail thật -->
<env name="CACHE_STORE" value="array"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="MAIL_MAILER" value="array"/>
<env name="PULSE_ENABLED" value="false"/>
<env name="TELESCOPE_ENABLED" value="false"/>
<!-- Database cách ly: SQLite In-memory -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>
</phpunit>
B. File .env.testing
Nếu dự án ưu tiên dùng .env.testing hơn phpunit.xml, tạo file .env.testing tại thư mục root:
APP_ENV=testing
APP_KEY=base64:FakeKeyForTestingPurposesOnly1234567890=
APP_DEBUG=true
BCRYPT_ROUNDS=4
CACHE_STORE=array
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_CONNECTION=sync
MAIL_MAILER=array
DB_CONNECTION=sqlite
DB_DATABASE=:memory:
3. Chiến lược Xử lý Database trong Kiểm thử
Chiến lược 1: SQLite In-memory (Mặc định - Khuyến nghị cho 90% Unit Test)
- Ưu điểm: Tốc độ cực nhanh (vài milliseconds), không tạo rác trên ổ cứng, tự hủy sau mỗi test process.
- Yêu cầu: PHP phải kích hoạt extension
pdo_sqlitevàsqlite3.
Chiến lược 2: Xử lý các hàm MySQL đặc thù (MySQL-specific functions)
Nếu code nguồn dùng các hàm raw của MySQL như JSON_EXTRACT, JSON_CONTAINS, DATE_FORMAT, SQLite sẽ văng lỗi no such function.
Cách xử lý:
- Đăng ký SQLite custom function trong
TestCase::setUp():protected function setUp(): void { parent::setUp(); if (DB::connection() instanceof \Illuminate\Database\SQLiteConnection) { $pdo = DB::connection()->getPdo(); // Giả lập hàm DATE_FORMAT của MySQL trong SQLite $pdo->sqliteCreateFunction('DATE_FORMAT', function ($date, $format) { return date('Y-m-d', strtotime($date)); }, 2); // Giả lập JSON_CONTAINS $pdo->sqliteCreateFunction('JSON_CONTAINS', function ($json, $val) { $array = json_decode($json, true) ?? []; return in_array(trim($val, '"'), $array) ? 1 : 0; }, 2); } } - Nếu dự án có quá nhiều Stored Procedures hoặc SQL phức tạp: Sử dụng một container MySQL test riêng (xem mục Docker bên dưới) thay vì SQLite.
4. Chạy Test qua Docker (Docker Integration)
Kịch bản 1: Dự án dùng Laravel Sail
Laravel Sail đã cấu hình sẵn container test:
# Chạy toàn bộ test
./vendor/bin/sail test
# Chạy riêng Unit Test
./vendor/bin/sail test --testsuite=Unit
# Chạy kèm tính Code Coverage
./vendor/bin/sail test --coverage
Kịch bản 2: Dự án dùng Custom Docker Compose
Xác định tên service PHP trong docker-compose.yml (thường là app, php, backend, workspace):
# Cú pháp chạy
docker compose exec -T <service_name> php artisan test
# Ví dụ với service 'app':
docker compose exec -T app php artisan test --testsuite=Unit --filter=UserServiceTest
Kịch bản 3: Docker Test Runner độc lập (templates/docker/docker-compose.test.yml)
Nếu dự án chưa có Docker hoặc môi trường Docker chính quá nặng nề, có thể khởi tạo một container test tối giản chỉ chứa PHP-CLI + SQLite + PCOV.
5. Cấu hình Code Coverage (PCOV vs Xdebug)
Để đo độ phủ test (Coverage):
- Khuyến nghị dùng PCOV: Nhanh gấp 5-10 lần Xdebug, chỉ phục vụ đo coverage không làm chậm quá trình chạy test.
- Cài đặt trên Ubuntu/Debian container:
pecl install pcov && docker-php-ext-enable pcov - Lệnh chạy:
php artisan test --coverage --min=80
- Cài đặt trên Ubuntu/Debian container:
- Nếu dùng Xdebug: Cần đặt biến môi trường
XDEBUG_MODE=coverage.
6. Checklist Kiểm tra Sẵn sàng (Ready-to-Test Checklist)
Trước khi bắt đầu sinh unit test, hãy xác nhận các mục sau:
- Đã chạy
composer installkhông lỗi. - Extension
pdo_sqliteđã được bật (kiểm tra bằngphp -m | grep sqlite). APP_KEYđã tồn tại trong file môi trường test.- Chạy lệnh
php artisan test(hoặc tương đương qua Docker) ra kết quả xanh (Pass) với các test mặc định của Laravel. - Đã cấu hình
DB_DATABASE=:memory:để bảo vệ dữ liệu dev/local.