feat: enforce exhaustive unit testing and 100% SonarQube branch coverage
- Enforce mandatory handle() and failed() method testing for all Jobs and Commands - Ban shallow reflection-only helper testing in Jobs - Mandate actual SQLite in-memory query execution for Repositories (ban Builder::class assertions alone) - Enforce full branch coverage for SonarQube (ternary, null-coalescing, catch blocks, match) - Update JobTest templates for PHPUnit and Pest to include handle() and failed() methods - Update verification checklist and master system prompt with strict branch gatekeepers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -83,10 +83,18 @@ 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 (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 (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 5: Sinh Mã Nguồn Test
|
||||
1. Xác định đường dẫn file test theo quy tắc Mirror:
|
||||
@@ -95,8 +103,9 @@ Người dùng có thể kích hoạt linh hoạt theo các chế độ (từ qu
|
||||
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()`.
|
||||
- Mock expectation có số lần gọi nghiêm ngặt: `->once()`, `->never()`.
|
||||
- Dùng Strict assertion: `$this->assertSame()` hoặc `expect(...)->toBe()`.
|
||||
- Đảm bảo quét sạch tất cả các nhánh điều kiện để SonarQube Line & Branch Coverage đạt > 85% - 95%.
|
||||
|
||||
### Bước 6: Thẩm định & Lưu File
|
||||
1. Tự kiểm tra file test qua `rules/verification-checklist.md`.
|
||||
|
||||
Reference in New Issue
Block a user