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:
2026-09-07 16:41:37 +07:00
commit 2045c856e9
60 changed files with 5248 additions and 0 deletions
@@ -0,0 +1,46 @@
---
name: laravel-mock-helper
description: Phân tích một Class hoặc Interface bất kỳ và tự động sinh khối mã thiết lập Mock (Mockery / Laravel Fakes) sẵn sàng đưa vào test.
---
# Skill: Laravel Mock Helper
Skill này hỗ trợ lập trình viên sinh nhanh mã giả lập (Mocking code) cho một Interface, Repository hoặc Service phức tạp.
## Cách kích hoạt
```text
/laravel-mock-helper <tên_class_hoặc_interface_hoặc_đường_dẫn>
```
*Ví dụ*: `/laravel-mock-helper App\Contracts\PaymentGatewayInterface`
---
## Quy trình xử lý của Agent:
1. Đọc nội dung file class/interface được cung cấp.
2. Liệt kê toàn bộ các `public methods`, bao gồm kiểu dữ liệu của tham số và kiểu trả về.
3. Sinh ra 2 phiên bản mã Mockery:
- **Phiên bản Happy Path (Thành công)**: Mock trả về dữ liệu mẫu chuẩn theo kiểu trả về.
- **Phiên bản Exception / Failure**: Mock ném ra ngoại lệ hoặc trả về `false`/`null`.
4. Sinh kèm cú pháp kiểm tra số lần gọi (`->once()`, `->withArgs(...)`).
## Mẫu kết quả trả về:
```php
// ==========================================
// THIẾT LẬP MOCK: PaymentGatewayInterface
// ==========================================
// 1. Khởi tạo mock
$gatewayMock = Mockery::mock(\App\Contracts\PaymentGatewayInterface::class);
// Kịch bản A: Happy Path
$gatewayMock->shouldReceive('charge')
->once()
->with(Mockery::type('float'), Mockery::type('string'))
->andReturn(new \App\DTOs\TransactionResult(success: true, id: 'TXN_123'));
// Kịch bản B: Exception Failure
$gatewayMock->shouldReceive('charge')
->once()
->andThrow(new \App\Exceptions\PaymentGatewayException('Connection timed out'));
```
@@ -0,0 +1,63 @@
---
name: laravel-test-review
description: Đánh giá, chấm điểm chất lượng và phát hiện các lỗi anti-patterns trong file Unit Test Laravel có sẵn.
---
# Skill: Laravel Test Reviewer
Skill này chịu trách nhiệm kiểm tra sức khỏe và chất lượng của một file test đã được viết sẵn trong dự án.
## Cách kích hoạt
```text
/laravel-test-review <đường_dẫn_file_test>
```
*Ví dụ*: `/laravel-test-review tests/Unit/Services/PaymentServiceTest.php`
---
## Tiêu Chí Đánh Giá (Scoring Criteria - Thang Điểm 100)
Agent sẽ quét file test qua 5 tiêu chí:
### 1. Tính Cô Lập & Tốc Độ (Isolation & Speed - 25đ)
- Test có vô tình kích hoạt kết nối Database thật không?
- Có bị gọi mạng ngoài thật (Real HTTP) mà quên `Http::fake()` không?
- Có dùng `sleep()` gây chậm test không?
### 2. Chiến Lược Giả Lập (Mocking Quality - 20đ)
- Có bị over-mocking (Mock cả DTO, Value Object, Model đơn giản) không?
- Mock method có ghi rõ số lần gọi (`->once()`, `->never()`) không hay chỉ dùng `shouldReceive()` vô thưởng vô phạt?
- Có bị lỗi mock chuỗi Eloquent Builder không?
### 3. Cấu Trúc & Assertions (Structure & Assertions - 20đ)
- Có phân tách rõ ràng mô hình AAA (`// Arrange`, `// Act`, `// Assert`) không?
- Assertions có chặt chẽ (`assertSame`, `toBe`) hay dùng loose assertion?
- Có assertion rỗng / vô nghĩa (`assertTrue(true)`) không?
### 4. Độ Phủ Kịch Bản (Scenario Coverage - 20đ)
- Ngoài Happy Path, đã có test case cho Exception chưa?
- Đã test các giá trị biên: `null`, mảng rỗng `[]`, số `0`, số âm chưa?
### 5. Khả Năng Bảo Trì (Maintainability & Cleanliness - 15đ)
- Tên test method có mô tả rõ ràng hành vi và ngữ cảnh không?
- Có dọn dẹp state / reset `Carbon::setTestNow()` để tránh rò rỉ trạng thái giữa các test không?
---
## Báo Cáo Đầu Ra Mẫu:
```markdown
### 🔍 BÁO CÁO REVIEW UNIT TEST: `PaymentServiceTest.php`
**Điểm tổng kết: 70/100 (Cần cải thiện)**
#### ⚠️ Các vấn đề phát hiện (Anti-Patterns):
1. **Over-mocking tại line 24**: Đang mock `PaymentDTO` thay vì khởi tạo instance thật. DTO chỉ mang dữ liệu, không có hành vi.
2. **Thiếu số lần gọi Mock tại line 35**: `$gatewayMock->shouldReceive('charge')` chưa có `->once()`. Nếu hàm không được gọi hoặc bị gọi 10 lần, test vẫn pass.
3. **Chưa có Exception Test**: Chưa kiểm thử kịch bản khi Gateway ném `PaymentGatewayException`.
#### 💡 Đề xuất Refactor:
```php
// Đoạn code được sửa lại chuẩn AAA và strict mock...
```
```
@@ -0,0 +1,91 @@
---
name: laravel-test-setup
description: Tự động quét kiểm tra môi trường, dependencies, database config và docker để chuẩn bị viết Unit Test cho bất kỳ dự án Laravel nào.
---
# Skill: Laravel Test Environment Setup & Health Check
Skill này chịu trách nhiệm chuẩn bị "Bước 0" cho dự án Laravel trước khi bắt đầu viết bất kỳ Unit Test nào.
## Cách kích hoạt
- **Chế độ kiểm tra (Dry-run / Health-Check)**:
```text
/laravel-test-setup
```
- **Chế độ tự động cài đặt gói thiếu (Auto-Install Mode)**:
```text
/laravel-test-setup --install
```
## Quy trình thực hiện (Execution Workflow)
Khi người dùng kích hoạt lệnh `/laravel-test-setup`, Agent sẽ tuần tự thực hiện các bước sau:
### Bước 1: Quét `composer.json` & Nhận Diện Thư Viện Cần Thiết
1. Đọc file `composer.json` tại thư mục gốc của dự án.
2. Xác định:
- **Phiên bản PHP & Laravel**: PHP 8.0 - 8.4+, Laravel 9.x - 13.x
- **Test Framework**: `phpunit/phpunit` hay `pestphp/pest`
- **Mocking & Fake**: `mockery/mockery`, `fakerphp/faker`
- **Performance & Coverage**: `brianium/paratest`, `nunomaduro/collision`
3. Nếu phát hiện thiếu thư viện:
- Nếu có cờ `--install` hoặc người dùng đồng ý: Agent tự động kích hoạt lệnh cài đặt qua môi trường tương ứng (Sail / Docker Compose / Local Composer):
```bash
# Nếu dùng Sail:
./vendor/bin/sail composer require --dev mockery/mockery fakerphp/faker --with-all-dependencies
# Nếu dùng Docker Compose (service app):
docker compose exec -T app composer require --dev mockery/mockery fakerphp/faker --with-all-dependencies
# Nếu chạy Local:
composer require --dev mockery/mockery fakerphp/faker --with-all-dependencies
```
- Hoặc chạy script `./setup-test-deps.sh` có sẵn.
### Bước 2: Kiểm tra cấu hình Testing Database & Drivers
1. Kiểm tra sự tồn tại của `phpunit.xml` (hoặc `phpunit.xml.dist`) hoặc `.env.testing`.
2. Xác thực cấu hình thẻ `<php>` trong `phpunit.xml`:
- `DB_CONNECTION` phải là `sqlite` và `DB_DATABASE` là `:memory:` (hoặc kết nối DB test riêng an toàn).
- `CACHE_STORE` hoặc `CACHE_DRIVER` phải là `array`.
- `QUEUE_CONNECTION` phải là `sync`.
- `MAIL_MAILER` phải là `array`.
- `BCRYPT_ROUNDS` nên là `4`.
3. Nếu chưa có hoặc cấu hình đang trỏ vào database dev thật:
- Cảnh báo người dùng về nguy cơ mất dữ liệu dev.
- Đề xuất tạo `.env.testing` hoặc cập nhật `phpunit.xml` dựa trên template có sẵn tại `templates/configs/`.
### Bước 3: Phát hiện Môi trường Docker / Runtime
1. Kiểm tra `./vendor/bin/sail` -> Nếu có Sail, ưu tiên lệnh `./vendor/bin/sail test`.
2. Kiểm tra `docker-compose.yml` -> Dò tìm service PHP (`app`, `php`, `backend`,...) -> Đề xuất lệnh `docker compose exec -T <service> php artisan test`.
3. Nếu chạy Local: Kiểm tra xem extension `pdo_sqlite` đã được bật chưa bằng `php -m | grep sqlite`.
### Bước 4: Chạy Smoke Test (Kiểm tra thử nghiệm)
1. Chạy thử nghiệm lệnh test hiện có của project (ví dụ: `php artisan test --filter=ExampleTest`).
2. Nếu test PASS: Báo cáo môi trường đã sẵn sàng 100% để sinh Unit Test.
3. Nếu test FAIL hoặc văng lỗi (ví dụ: thiếu APP_KEY, thiếu SQLite driver, lỗi database): Đưa ra chẩn đoán chính xác nguyên nhân và lệnh khắc phục.
---
## Mẫu báo cáo đầu ra cho người dùng:
```markdown
### 📋 BÁO CÁO MÔI TRƯỜNG TEST (HEALTH CHECK)
1. **Framework & Dependencies**:
- Laravel: 11.2.0 | PHP: 8.3
- Test Runner: Pest PHP v2.34
- Mocking: Mockery 1.6 (Đã cài)
- Faker: FakerPHP 1.23 (Đã cài)
2. **Cấu hình Môi trường**:
- DB Test: SQLite (:memory:) [OK - An toàn]
- Cache / Queue / Mail: Array / Sync [OK - Tối ưu]
- BCRYPT_ROUNDS: 4 [OK - Tốc độ cao]
3. **Môi trường thực thi**:
- Docker Service: `app` container đang hoạt động
- Lệnh chạy test chuẩn: `docker compose exec -T app php artisan test`
4. **Kết quả Smoke Test**:
- Trạng thái: ✅ PASSED (2 tests, 4 assertions)
🎉 **Môi trường đã hoàn toàn sẵn sàng cho việc sinh Unit Test!**
```
+99
View File
@@ -0,0 +1,99 @@
---
name: laravel-unit-test
description: Phân tích một class mã nguồn PHP Laravel bất kỳ và tự động sinh file Unit Test hoàn chỉnh đạt chuẩn AAA, cô lập cao và bao phủ biên.
---
# Skill: Laravel Unit Test Generator
Skill này là công cụ chính để tự động tạo ra file Unit Test cho bất kỳ class nào trong dự án Laravel (Service, Action, Controller, Job, FormRequest, Policy, Rule,...).
## Cách kích hoạt
Người dùng có thể kích hoạt linh hoạt theo các chế độ (từ 1 lệnh duy nhất cho toàn bộ dự án đến từng file đơn lẻ):
1. **🌟 Chế độ 1 Lệnh Duy Nhất Cho Toàn Bộ Dự Án (All-in-One Full Coverage Mode - Khuyên dùng cho dự án lớn)**:
```text
/laravel-unit-test --all
```
**Cơ chế cam kết không bỏ sót bất kỳ file nào:**
- **Giai đoạn 1 (Lập Manifest Kiểm Soát)**: Tự động quét toàn bộ `app/` (và `Modules/`), lọc ra tất cả các class có logic (Services, Actions, FormRequests, Rules, Jobs, Policies, Middlewares, Listeners, Observers, Repositories, Custom Casts). Lập file danh sách kiểm soát `tests/.test-manifest.json` (ví dụ: Tổng cộng 42 files).
- **Giai đoạn 2 (Thực Thi Tuần Tự & Theo Dõi Tiến Độ)**: Duyệt tuần tự từng class trong manifest (`[1/42]`, `[2/42]`,...), sinh test tương ứng và đánh dấu `[COMPLETED]`. Không bao giờ bị tràn context và có thể tiếp tục nếu bị gián đoạn.
- **Giai đoạn 3 (Tự Động Chạy Thử & Sửa Lỗi Ngay - Auto-Healing)**: Sinh xong file nào lập tức chạy `./test-runner.sh --filter=<Test>` cho file đó. Nếu FAIL -> Tự động đọc log lỗi và sửa lại test cho đến khi PASS 100%.
- **Giai đoạn 4 (Báo Cáo Nghiệm Thu Độ Phủ)**: Chạy `./test-runner.sh --coverage` và in bảng tổng kết: `42/42 files covered, 100% Passed, Code Coverage: > 80%`.
2. **Chế độ Hàng loạt theo Thư mục (Batch Directory Mode)**:
```text
/laravel-unit-test app/Services/
# Hoặc:
/laravel-unit-test app/Actions/
```
3. **Chế độ Theo Module / DDD (Module Mode)**:
```text
/laravel-unit-test Modules/Order/
# Hoặc:
/laravel-unit-test app/Domains/Payment/
```
4. **Chế độ Quét & Phủ Test Toàn Dự Án (Untested Audit Mode)**:
```text
/laravel-unit-test --untested
```
5. **Chế độ Theo Git Diff (Changed Files Mode - Dành Cho Pull Request)**:
```text
/laravel-unit-test --changed
```
6. **Chế độ File đơn lẻ (Single File Mode)**:
```text
/laravel-unit-test app/Services/PaymentService.php
```
---
## Quy trình 6 Bước Tự Động của Agent
### Bước 1: Khảo sát Môi trường & Framework
1. Đọc `composer.json` để xác định Framework test của dự án:
- Nếu có `pestphp/pest`: Tạo test theo định dạng **Pest PHP**.
- Nếu có `phpunit/phpunit`:
- PHP >= 8.1 & PHPUnit 10+: Dùng **PHP 8 Attributes (`#[Test]`, `#[DataProvider]`)**.
- PHP < 8.1 hoặc PHPUnit 9: Dùng **DocBlock (`/** @test */`)**.
### Bước 2: Phân tích File Nguồn
1. Đọc toàn bộ nội dung file class nguồn được chỉ định.
2. Xác định:
- **Loại Component**: Service, Action, Controller, FormRequest, Model, Job, Policy, Middleware,...
- **Constructor Dependencies**: Các class/interface được inject vào qua `__construct()`.
- **Public Methods**: Danh sách các hàm cần test.
- **Kiểu dữ liệu & Logic phân nhánh**: Các lệnh `if/else`, `try/catch`, `throw`, type hints của params và return types.
### Bước 3: Phân Loại Mock vs Real Object
- **Mock bằng Mockery**: Các Interface, Repository, 3rd Party Client, Mailer, Logger.
- **Dùng Laravel Fakes**: `Http::fake()`, `Queue::fake()`, `Event::fake()`, `Storage::fake()`.
- **Dùng Object thật (Không Mock)**: DTOs, Value Objects, Collections, Request payload dạng mảng.
### Bước 4: Lập Ma Trận Test Scenarios (Tối thiểu cho mỗi public method)
- **1 Happy Path**: Đầu vào hợp lệ -> Thực thi thành công -> Trả về đúng kết quả.
- **N Edge Cases**: Input biên (0, số âm, rỗng `""`, `[]`, `null`, unicode).
- **N Exception Cases**: Tham số sai ném `InvalidArgumentException`, service ngoài lỗi ném `PaymentFailedException`,...
### Bước 5: Sinh Mã Nguồn Test
1. Xác định đường dẫn file test theo quy tắc Mirror:
- Nguồn: `app/Services/OrderService.php`
- Đích: `tests/Unit/Services/OrderServiceTest.php`
2. Tham chiếu hướng dẫn tương ứng trong `docs/components/` và template trong `templates/`.
3. Viết đầy đủ code:
- Tuân thủ mô hình **AAA** (`// Arrange`, `// Act`, `// Assert`).
- Mock expectation có số lần gọi rõ ràng: `->once()`, `->never()`.
- Dùng Strict assertion: `$this->assertSame()` hoặc `expect(...)->toBe()`.
### Bước 6: Thẩm định & Lưu File
1. Tự kiểm tra file test qua `rules/verification-checklist.md`.
2. Ghi file test vào thư mục `tests/Unit/...`.
3. In ra lệnh chạy test gợi ý:
```bash
php artisan test --filter=OrderServiceTest
# Hoặc qua docker runner:
./templates/docker/test-runner.sh --filter=OrderServiceTest
```