feat: complete Smartgift AI Laravel unit testing toolkit
- 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>
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
# 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.0` hoặc `pestphp/pest: ^2.0`.
|
||||
- **Laravel 11 (PHP 8.2 - 8.3+)**: Mặc định `pestphp/pest: ^2.0|^3.0` hoặc `phpunit/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:
|
||||
```bash
|
||||
composer require --dev phpunit/phpunit mockery/mockery fakerphp/faker --with-all-dependencies
|
||||
```
|
||||
|
||||
#### Nếu dự án dùng Pest PHP:
|
||||
```bash
|
||||
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)**:
|
||||
```bash
|
||||
composer require --dev brianium/paratest
|
||||
# Laravel 9+ có sẵn lệnh: php artisan test --parallel
|
||||
```
|
||||
- **Làm đẹp output CLI**:
|
||||
```bash
|
||||
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
|
||||
<?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:
|
||||
```ini
|
||||
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_sqlite` và `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ý:**
|
||||
1. Đăng ký SQLite custom function trong `TestCase::setUp()`:
|
||||
```php
|
||||
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);
|
||||
}
|
||||
}
|
||||
```
|
||||
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:
|
||||
```bash
|
||||
# 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`):
|
||||
```bash
|
||||
# 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`
|
||||
- **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:
|
||||
1. [ ] Đã chạy `composer install` không lỗi.
|
||||
2. [ ] Extension `pdo_sqlite` đã được bật (kiểm tra bằng `php -m | grep sqlite`).
|
||||
3. [ ] `APP_KEY` đã tồn tại trong file môi trường test.
|
||||
4. [ ] 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.
|
||||
5. [ ] Đã cấu hình `DB_DATABASE=:memory:` để bảo vệ dữ liệu dev/local.
|
||||
Reference in New Issue
Block a user