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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user