feat: enforce >90% SonarQube coverage rules and exclusions for Laravel

- Enhance laravel-unit-test skill with layer-by-layer branch coverage rules
- Expand Laravel boilerplate exclusions in sonar-project.properties template
- Update SonarQube guide with Laravel comprehensive exclusions
This commit is contained in:
2026-09-14 10:33:35 +07:00
parent 8f7212ef65
commit 97f3833bf2
3 changed files with 37 additions and 15 deletions
+34 -12
View File
@@ -83,18 +83,40 @@ Người dùng có thể kích hoạt linh hoạt theo các chế độ (từ qu
- **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 (Bắt Buộc Đầy Đủ & Không Bỏ Sót)
- **Bắt buộc 100% Public Methods**: Mọi phương thức public đều phải có test.
- *Nếu là Job / Command*: **BẮT BUỘC 100% phải test phương thức `handle()`** và `failed()`. Tuyệt đối CẤM chỉ test hàm helper phụ (`buildRedisKey`) bằng reflection!
- *Nếu là Repository*: **BẮT BUỘC phải test kết quả truy vấn / cập nhật dữ liệu thật** trên SQLite in-memory, tuyệt đối CẤM chỉ assert `Builder::class`!
- **Bao phủ 100% nhánh rẽ SonarQube**:
- Mọi toán tử `??` (Null Coalescing) và `?:` (Ternary) phải có test case cho cả 2 vế.
- Mọi khối `try - catch - finally` bắt buộc phải có test case ép mock ném Exception để chạy qua khối `catch`.
- Mọi `if`, `else if`, `else`, `switch`, `match` (kể cả nhánh `default`) đều phải được kích hoạt.
- **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 4: Lập Ma Trận Test Scenarios (Đảm Bảo Coverage > 90% Trên SonarQube)
Mục tiêu cốt lõi: SonarQube tính cả Line Coverage và Branch Coverage. Để đạt **Coverage > 90%**, Agent phải tuân thủ nghiêm ngặt ma trận sau:
1. **100% Public Methods**: Mọi phương thức public của class đều phải có bài test.
2. **Quét 100% Nhánh Rẽ (Branch / Condition Coverage)**:
- **Toán tử `??` (Null Coalescing)**: Bắt buộc 2 test case (có giá trị & null/fallback).
- **Toán tử `?:` (Ternary)**: Bắt buộc 2 test case (true & false).
- **Biểu thức logic `&&` và `||`**: Phải test các kịch bản kết hợp để thỏa mãn điều kiện rẽ nhánh SonarQube.
- **Khối `try - catch - finally`**: BẮT BUỘC có test case ép mock ném Exception để chạy qua khối `catch`.
- **Mọi `if`, `else if`, `else`, `switch`, `match`** (kể cả nhánh `default`).
3. **Chiến Lược Riêng Cho Từng Tầng Laravel Để Đạt > 90%**:
- **FormRequest (`app/Http/Requests/`)**:
- Test `authorize()` trả về cả `true` (cho phép) và `false` (từ chối).
- Test `rules()`: Bắt buộc test dữ liệu hợp lệ VÀ test vi phạm cho **từng rule** (`required`, `email`, `max`, `numeric`, `unique`) để phủ 100% các nhánh validator.
- **Custom Rules (`app/Rules/`)**: Test cả 2 trường hợp `passes() === true` và `passes() === false` (kèm thông báo `message()`).
- **Controllers (`app/Http/Controllers/`)**:
- Endpoint Success: 200 OK hoặc 201 Created.
- Validation Error: 422 Unprocessable Entity khi payload thiếu/sai.
- Unauthorized: 401 Unauthenticated hoặc 403 Forbidden.
- Not Found: 404 khi Model ID không tồn tại.
- **Services & Actions (`app/Services/`, `app/Actions/`)**:
- Happy Path: Đầu vào chuẩn -> kết quả đúng.
- Exception Path: Bắt buộc test mock ném ngoại lệ (`PaymentFailedException`,...).
- Nếu có `DB::transaction()`: Test cả commit thành công và rollback khi gặp lỗi.
- **Jobs (`app/Jobs/`)**:
- BẮT BUỘC test phương thức **`handle()`** (với đầy đủ mock S3, Queue, DB, Mail).
- BẮT BUỘC test phương thức **`failed(Throwable $e)`**. Tuyệt đối cấm chỉ test helper phụ.
- **Policies (`app/Policies/`)**:
- Mọi action (`view`, `create`, `update`, `delete`,...) bắt buộc test cả 2 kịch bản: `true` (User có quyền) và `false` (User không có quyền).
- **Artisan Commands (`app/Console/Commands/`)**:
- Test exit code 0 (`assertExitCode(0)`) khi arguments hợp lệ.
- Test exit code 1 khi thiếu arguments hoặc command gặp Exception.
- **Repositories (`app/Repositories/`)**:
- Test kết quả truy vấn / cập nhật dữ liệu thật trên SQLite in-memory (cấm chỉ assert `Builder::class`).
### Bước 5: Sinh Mã Nguồn Test
1. Xác định đường dẫn file test theo quy tắc Mirror: