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,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!**
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user