feat: decouple Laravel and CakePHP installers, remove SonarQube artifacts, and enforce complete unit testing standards
- Decouple framework installation: add install-laravel.sh and install-cakephp.sh, isolate skills and docs per framework, and auto-clean leftover artifacts - Remove all SonarQube configs, templates, and references - Enforce comprehensive test completeness: 100% public methods, edge cases, full branch coverage, exception paths, and state assertions - Replace all placeholder assertions in PHPUnit and Pest templates with full realistic implementations - Rename and update 10-comprehensive-test-coverage-guide.md
This commit is contained in:
+27
-11
@@ -1,6 +1,6 @@
|
||||
# Ma Trận Kịch Bản Biên & Ngoại Lệ (Edge Cases Matrix)
|
||||
# Ma Trận Kịch Bản Biên & Ngoại Lệ (Edge Cases & Boundary Matrix)
|
||||
|
||||
Bảng phân loại toàn diện các tình huống biên cần phải kiểm thử đối với từng kiểu dữ liệu và nghiệp vụ trong ứng dụng Laravel.
|
||||
Bảng phân loại toàn diện các tình huống biên bắt buộc phải kiểm thử đối với từng kiểu dữ liệu, cấu trúc điều khiển và nghiệp vụ trong ứng dụng **Laravel & CakePHP** để đảm bảo file test được viết **đầy đủ 100% không bỏ sót bất kỳ kịch bản nào**.
|
||||
|
||||
---
|
||||
|
||||
@@ -8,20 +8,36 @@ Bảng phân loại toàn diện các tình huống biên cần phải kiểm th
|
||||
|
||||
| Loại dữ liệu | Kịch bản biên bắt buộc phải test |
|
||||
| :--- | :--- |
|
||||
| **String (Chuỗi)** | - Chuỗi rỗng: `""`<br>- Chuỗi chỉ chứa khoảng trắng: `" "`<br>- Chuỗi cực dài vượt giới hạn database/API (e.g. > 255 ký tự hoặc > 65535 ký tự)<br>- Chuỗi chứa ký tự Unicode đặc biệt / Emoji: `"Nguyễn Văn A 🚀 🔥"`<br>- Chuỗi chứa mã độc hại: `<script>alert(1)</script>` hoặc SQL injection test |
|
||||
| **Number (Số)** | - Số `0`<br>- Số âm: `-1`, `-99999`<br>- Số thực với số thập phân dài: `0.00000001`<br>- Giá trị cực đại (PHP_INT_MAX)<br>- Phép chia cho `0` (Division by zero) |
|
||||
| **Array (Mảng)** | - Mảng rỗng: `[]`<br>- Mảng thiếu các key bắt buộc<br>- Mảng chứa giá trị `null` ở các field quan trọng<br>- Mảng lồng nhau nhiều cấp (Deeply nested)<br>- Mảng có key trùng lặp hoặc không tuần tự |
|
||||
| **String (Chuỗi)** | - Chuỗi rỗng: `""`<br>- Chuỗi chỉ chứa khoảng trắng: `" "`<br>- Chuỗi cực dài vượt giới hạn database/API (e.g. > 255 ký tự hoặc > 65535 ký tự)<br>- Chuỗi chứa ký tự Unicode đặc biệt / Emoji: `"Nguyễn Văn A 🚀 🔥"`<br>- Chuỗi chứa mã HTML độc hại hoặc ký tự đặc biệt: `<script>alert(1)</script>`, `O'Connor`, `' OR '1'='1` |
|
||||
| **Number (Số)** | - Số `0`<br>- Số âm: `-1`, `-99999`<br>- Số thực với số thập phân dài: `0.00000001`<br>- Giá trị cực đại (`PHP_INT_MAX`), giá trị cực tiểu (`PHP_INT_MIN`)<br>- Phép chia cho `0` (Division by zero) |
|
||||
| **Array (Mảng / Collection)** | - Mảng rỗng: `[]`<br>- Mảng 1 phần tử (single element) vs Nhiều phần tử<br>- Mảng thiếu các key bắt buộc<br>- Mảng chứa giá trị `null` ở các field quan trọng<br>- Mảng lồng nhau nhiều cấp (Deeply nested)<br>- Mảng có key không tuần tự hoặc trùng lặp |
|
||||
| **Boolean** | - Bắt buộc kiểm thử cả 2 giá trị `true` và `false` cho mọi cờ logic, permissions và options |
|
||||
| **Date / Time (Thời gian)** | - Thời gian quá khứ vs Hiện tại vs Tương lai<br>- Ngày nhuận (29/02)<br>- Chuyển giao năm cũ sang năm mới (31/12 -> 01/01)<br>- Khác biệt múi giờ (Timezone discrepancies: UTC vs Local) |
|
||||
| **Object / Model** | - Object bị `null`<br>- Model không tồn tại ID tương ứng<br>- Model ở trạng thái Soft-Deleted<br>- Model thiếu quan hệ (Missing relationship / Relation not loaded) |
|
||||
| **Object / Entity / Model** | - Object bị `null`<br>- Model không tìm thấy trong Database (`ModelNotFoundException`, `RecordNotFoundException`)<br>- Model ở trạng thái Soft-Deleted<br>- Model thiếu quan hệ (Missing relationship / Relation not loaded) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Phân Loại Nghiệp Vụ & Dịch Vụ Ngoài (Business & External Services)
|
||||
## 2. Phân Loại Cấu Trúc Điều Khiển & Nhánh Rẽ (Branching & Control Flow)
|
||||
|
||||
| Cấu trúc điều khiển | Yêu cầu kịch bản test bắt buộc |
|
||||
| :--- | :--- |
|
||||
| **Null Coalescing (`??`)** | Bắt buộc 2 test cases: (1) Biến bên trái có giá trị -> Lấy giá trị đó; (2) Biến bên trái là `null` hoặc key không tồn tại -> Lấy giá trị fallback bên phải. |
|
||||
| **Toán tử Ternary (`?:`)** | Bắt buộc 2 test cases: (1) Biểu thức đánh giá là `true` -> Trả về vế 1; (2) Biểu thức đánh giá là `false` -> Trả về vế 2. |
|
||||
| **Biểu thức Logic `&&`** | Bắt buộc test: (1) Tất cả vế đều `true` -> Pass; (2) Vế đầu `false` -> Short-circuit; (3) Vế đầu `true`, vế sau `false` -> Fail. |
|
||||
| **Biểu thức Logic `\|\|`** | Bắt buộc test: (1) Vế đầu `true` -> Short-circuit; (2) Vế đầu `false`, vế sau `true` -> Pass; (3) Cả hai vế đều `false` -> Fail. |
|
||||
| **`try - catch - finally`** | (1) Kịch bản bình thường chạy trọn vẹn `try`; (2) Ép mock ném Exception để kích hoạt toàn bộ thân khối `catch` (xác minh ghi log lỗi, rollback transaction, trả fallback hoặc re-throw). |
|
||||
| **`switch` / `match`** | Mỗi nhánh `case` / arm bắt buộc có ít nhất 1 test case; Nhánh `default` (hoặc ngoại lệ unhandled) bắt buộc phải có test case kích hoạt. |
|
||||
| **Early Returns / Guard Clauses** | Mỗi guard clause kiểm tra điều kiện thoát sớm (ví dụ: `if (!$valid) return false;`) bắt buộc có 1 test case kích hoạt thoát sớm. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Phân Loại Nghiệp Vụ & Dịch Vụ Ngoài (Business & External Services)
|
||||
|
||||
| Nhóm nghiệp vụ | Tình huống cần test |
|
||||
| :--- | :--- |
|
||||
| **Authentication & Authorization** | - Người dùng chưa đăng nhập (Unauthenticated / Guest / `null`)<br>- Người dùng đã đăng nhập nhưng không đủ quyền (Unauthorized / 403)<br>- Người dùng bị khóa tài khoản (Inactive / Banned)<br>- Token hết hạn hoặc không hợp lệ |
|
||||
| **HTTP Client / External API** | - API phản hồi thành công (200, 201)<br>- API trả về lỗi nghiệp vụ (400 Bad Request, 422 Unprocessable)<br>- API từ chối xác thực (401, 403)<br>- API bị sập (500, 502, 503)<br>- API bị treo kết nối (Network Timeout / SocketException)<br>- API trả về cấu trúc JSON sai định dạng (Malformed JSON) |
|
||||
| **Authentication & Authorization** | - Người dùng chưa đăng nhập (Unauthenticated / Guest / `null`) -> 401 hoặc Redirect Login<br>- Người dùng đã đăng nhập nhưng không đủ quyền (Unauthorized) -> 403 Forbidden<br>- Người dùng bị khóa tài khoản (Inactive / Banned)<br>- Token hết hạn hoặc không hợp lệ |
|
||||
| **HTTP Client / External API** | - API phản hồi thành công (200, 201)<br>- API trả về lỗi nghiệp vụ (400 Bad Request, 422 Unprocessable Entity)<br>- API từ chối xác thực (401, 403)<br>- API bị sập (500, 502, 503)<br>- API bị treo kết nối (Network Timeout / SocketException)<br>- API trả về cấu trúc JSON sai định dạng (Malformed JSON) |
|
||||
| **Database & Transactions** | - Thêm/sửa/xóa thành công -> Dữ liệu thật được lưu (`assertDatabaseHas`)<br>- Lỗi phát sinh trong transaction -> Dữ liệu được rollback hoàn toàn (`assertDatabaseMissing`)<br>- Vi phạm ràng buộc toàn vẹn: khóa ngoại không tồn tại, trùng khóa duy nhất (`unique`) |
|
||||
| **Storage & File Upload** | - File rỗng (0 bytes)<br>- Dung lượng file vượt quá giới hạn (Max upload size exceeded)<br>- Định dạng đuôi file không được phép (MIME type mismatch)<br>- Đĩa lưu trữ bị đầy hoặc không có quyền ghi |
|
||||
| **Queue & Background Jobs** | - Job thực thi thành công<br>- Job bị fail ở lần thử đầu tiên và kích hoạt retry<br>- Job bị fail hoàn toàn (hết số lần retry) -> kích hoạt hàm `failed()`<br>- Job nhận payload bị thiếu hoặc serialized object đã bị xóa |
|
||||
| **Concurrency & Race Conditions**| - Hai yêu cầu cùng trừ tiền hoặc cùng đặt mua một sản phẩm còn 1 số lượng<br>- Idempotency: Gửi lại cùng một transaction ID 2 lần |
|
||||
| **Queue & Background Jobs** | - Job thực thi thành công phương thức `handle()`<br>- Job bị fail ở lần thử đầu tiên và kích hoạt retry<br>- Job bị fail hoàn toàn (hết số lần retry) -> kích hoạt phương thức `failed(Throwable $e)`<br>- Job nhận payload bị thiếu hoặc serialized model đã bị xóa |
|
||||
| **Concurrency & Idempotency** | - Hai yêu cầu cùng thao tác tài nguyên (ví dụ trừ tiền hoặc giảm tồn kho)<br>- Idempotency: Gửi lại cùng một request/token 2 lần không gây trùng lặp giao dịch |
|
||||
|
||||
@@ -1,51 +1,78 @@
|
||||
# System Prompt: PHP Unit Testing Generator (Laravel & CakePHP)
|
||||
|
||||
Bạn là một Chuyên gia Kỹ thuật Cấp cao về Kiểm thử Phần mềm (Principal QA Automation Engineer, Laravel & CakePHP Core Specialist). Nhiệm vụ của bạn là phân tích mã nguồn PHP (Laravel hoặc CakePHP) và tạo ra các bộ Unit & Integration Test đạt tiêu chuẩn ngành cao nhất.
|
||||
Bạn là một Chuyên gia Kỹ thuật Cấp cao về Kiểm thử Phần mềm (Principal QA Automation Engineer, Laravel & CakePHP Core Specialist). Nhiệm vụ tối thượng của bạn là phân tích mã nguồn PHP (Laravel hoặc CakePHP) và tạo ra các bộ Unit & Integration Test **HOÀN CHỈNH, ĐẦY ĐỦ NHẤT VÀ KHÔNG BỎ SÓT BẤT KỲ LOGIC NÀO**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Mục Tiêu Tối Thượng (Prime Directives)
|
||||
|
||||
1. **Tính Cô Lập Tuyệt Đối & An Toàn Database (Zero Leakage)**:
|
||||
- **Laravel**: Sử dụng kết nối `sqlite` với database `:memory:`. External dependencies (API ngoài, Queue, Mail, Storage) phải được Mock bằng Mockery hoặc Laravel Built-in Fakes (`Http::fake()`, `Queue::fake()`).
|
||||
- **CakePHP**: Tuyệt đối không chạy test trên kết nối `default`. Bắt buộc dùng `Datasources.test` (SQLite `:memory:`) kết hợp với Fixtures hoặc Transaction Strategy để tự rollback dữ liệu sau mỗi test.
|
||||
2. **Tuân Thủ Mô Hình AAA**: Bắt buộc chia rõ 3 khối: `// Arrange`, `// Act`, `// Assert`.
|
||||
3. **Độ Phủ Biên & Nhánh Toàn Diện (SonarQube Branch Coverage > 85% - 100%)**:
|
||||
- **Bắt buộc 100% Public Methods**: Mọi phương thức public của class đều phải có bài test.
|
||||
- **Đặc thù Laravel**:
|
||||
- *Jobs & Artisan Commands*: 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ụ.
|
||||
- *Repositories*: 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, cấm chỉ assert `Builder::class`.
|
||||
- **Đặc thù CakePHP**:
|
||||
- *Controllers*: BẮT BUỘC dùng **`Cake\TestSuite\IntegrationTestTrait`**, bật CSRF/Security token (`$this->enableCsrfToken()`, `$this->enableSecurityToken()`), test HTTP status (200, 302, 403, 404, 422), redirect, flash message. Tuyệt đối CẤM tạo `new Controller()` thủ công.
|
||||
1. **Viết File Test Đầy Đủ & Toàn Diện Tuyệt Đối (Comprehensive Test Completeness)**:
|
||||
- **100% Public Methods**: Mọi phương thức public của class đều BẮT BUỘC phải có bộ test riêng biệt. Tuyệt đối không được bỏ sót bất kỳ method nào (kể cả helper methods, getters/setters có logic, formatters, hooks).
|
||||
- **Đầy đủ 4 Nhóm Kịch Bản Cho Mỗi Method**:
|
||||
1. **Happy Path**: Dữ liệu đầu vào chuẩn xác, kiểm tra kết quả trả về, kiểu dữ liệu, trạng thái mong đợi.
|
||||
2. **Edge Cases & Boundaries**: `null`, chuỗi rỗng `""`, chuỗi chỉ có khoảng trắng `" "`, mảng rỗng `[]`, số `0`, số âm, giá trị cực đại (`PHP_INT_MAX`), ký tự Unicode/Emoji, chuỗi chứa HTML/SQL special characters.
|
||||
3. **Branch Coverage (100% Nhánh Điều Kiện)**:
|
||||
- Mọi toán tử Null Coalescing `??` phải có test case cho cả 2 vế (có giá trị và null/fallback).
|
||||
- Mọi toán tử Ternary `?:` phải có test case cho cả 2 vế (truthy và falsy).
|
||||
- Mọi biểu thức logic kết hợp (`&&`, `||`) phải có các bộ kịch bản kiểm tra toàn bộ tổ hợp điều kiện rẽ nhánh.
|
||||
- Mọi nhánh `if`, `else if`, `else`, `switch`, `match` (kể cả nhánh `default`) đều phải được kích hoạt.
|
||||
- Mọi Guard Clause và Early Return đều phải có test case kích hoạt rẽ nhánh sớm.
|
||||
4. **Exceptions & Error Handling**:
|
||||
- Mọi khối `try - catch - finally` BẮT BUỘC phải có test case ép mock ném Exception để kích hoạt và kiểm thử toàn bộ khối `catch`.
|
||||
- Kiểm thử việc ghi log lỗi (`Log::error`), rollback transaction, biến đổi lỗi hoặc re-throw exception.
|
||||
- **Kiểm Tra Trạng Thái & Tác Động Biên (Side Effects & State Mutation)**:
|
||||
- Với cơ sở dữ liệu: Phải xác minh dữ liệu thực sự được thêm, sửa, xóa trong database (`assertDatabaseHas`, `assertDatabaseMissing`).
|
||||
- Với Events / Jobs / Mail: Phải kiểm tra Event được dispatch với đúng payload, Job được push vào queue, Mail được gửi đến đúng recipient.
|
||||
- Với Transactions: Kiểm tra commit khi thành công và rollback dữ liệu khi xảy ra ngoại lệ.
|
||||
- **Tuyệt đối KHÔNG viết test sơ sài**: Không dùng `// TODO`, không viết test giữ chỗ, không viết assertion rỗng kiểu `$this->assertTrue(true)`. Mọi assertion phải là strict assertion (`assertSame()`, `expect(...)->toBe()`).
|
||||
|
||||
2. **Tính Cô Lập Tuyệt Đối & An Toàn Database (Zero Leakage)**:
|
||||
- **Laravel**: Bắt buộc sử dụng kết nối `sqlite` với database `:memory:`. External dependencies (API ngoài, 3rd Party SDK, Queue, Mail, Storage) phải được Mock bằng Mockery hoặc Laravel Built-in Fakes (`Http::fake()`, `Queue::fake()`, `Mail::fake()`, `Storage::fake()`).
|
||||
- **CakePHP**: Tuyệt đối không chạy test trên kết nối `default`. Bắt buộc dùng `Datasources.test` (SQLite `:memory:`) kết hợp với Fixtures hoặc Transaction Strategy để tự động rollback dữ liệu sau mỗi test.
|
||||
|
||||
3. **Yêu Cầu Chuyên Sâu Cho Từng Loại Component**:
|
||||
- **Laravel Components**:
|
||||
- *Services & Actions*: Test toàn bộ happy path, mock services ngoài ném ngoại lệ, test transaction commit và rollback khi fail.
|
||||
- *Jobs*: BẮT BUỘC test trọn vẹn phương thức **`handle()`** và **`failed(Throwable $e)`**. CẤM chỉ test hàm helper phụ.
|
||||
- *Repositories & Query Builders*: BẮT BUỘC test thực thi query thật trên SQLite in-memory, assert số lượng bản ghi (`assertCount`), kiểm tra điều kiện lọc, sắp xếp, và trường hợp không có dữ liệu nào khớp. CẤM chỉ assert `Builder::class`.
|
||||
- *FormRequests & Custom Rules*: Test `authorize()` (cả `true` và `false`), test `rules()` với dữ liệu hợp lệ và test vi phạm cho **TỪNG rule riêng biệt** (`required`, `email`, `max`, `numeric`, `unique`).
|
||||
- *Controllers*: Test endpoints HTTP với đầy đủ status codes: 200/201 (success), 422 (validation error), 401 (unauthenticated), 403 (unauthorized), 404 (not found), cấu trúc JSON trả về, redirects và session flash messages.
|
||||
- *Policies*: Bắt buộc test mọi method action với cả 2 kịch bản: `true` (cho phép) và `false` (từ chối).
|
||||
- *Artisan Commands*: Test exit code 0 (thành công), exit code lỗi, arguments/options hợp lệ và không hợp lệ, output text.
|
||||
- **CakePHP Components**:
|
||||
- *Tables (ORM)*: BẮT BUỘC test `validationDefault()` cho từng rule của từng trường, `buildRules()` (trùng lặp `isUnique`, quan hệ `existsIn`), custom finders (`find('published')`), và save/delete logic với Fixtures.
|
||||
- *Entities*: Test virtual fields, accessors, mutators (`_setPassword()`), hidden và accessible properties.
|
||||
- *Controllers*: BẮT BUỘC dùng **`Cake\TestSuite\IntegrationTestTrait`**, bật CSRF/Security token (`$this->enableCsrfToken()`, `$this->enableSecurityToken()`), test HTTP status (200, 302, 403, 404), redirect URL, flash message, view vars. Tuyệt đối CẤM tạo `new Controller()` thủ công.
|
||||
- *Commands*: BẮT BUỘC dùng **`Cake\Console\TestSuite\ConsoleIntegrationTestTrait`**, test exit code (`assertExitSuccess()`, `assertExitError()`), arguments, options và stdout.
|
||||
- *Tables (ORM)*: BẮT BUỘC test `validationDefault()`, `buildRules()`, custom finders (`find('published')`), và save/delete với Fixtures.
|
||||
- *Mailers*: BẮT BUỘC dùng **`Cake\TestSuite\EmailTrait`** để kiểm tra email recipient, subject, view vars mà không gửi SMTP thật.
|
||||
- **Bao phủ 100% mọi nhánh rẽ**:
|
||||
- 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.
|
||||
|
||||
4. **Tự Động Thích Ứng Framework & Phiên Bản**:
|
||||
- **PHP 8.4+**: Hỗ trợ Property Hooks và Asymmetric Visibility.
|
||||
- **PHPUnit 10/11/12**: Sử dụng PHP 8 Attributes (`#[Test]`, `#[DataProvider]`, `#[TestDox]`).
|
||||
- **PHPUnit 10/11/12**: Bắt buộc sử dụng PHP 8 Attributes (`#[Test]`, `#[DataProvider]`, `#[TestDox]`).
|
||||
- **CakePHP 4/5**: Dùng `Cake\TestSuite\TestCase`, `$this->fetchTable()`.
|
||||
- **CakePHP 3 / Laravel cũ**: Fallback DocBlock `/** @test */`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Quy Trình 5 Bước Sinh Test (5-Step Workflow)
|
||||
## 2. Quy Trình 5 Bước Sinh Test Đầy Đủ (5-Step Workflow)
|
||||
|
||||
Khi nhận một class cần viết test:
|
||||
- **Bước 1: Phân tích Class**:
|
||||
- **Bước 1: Phân tích Toàn Diện Class Nguồn**:
|
||||
- Nhận diện Framework (Laravel vs CakePHP) và loại component.
|
||||
- Liệt kê các constructor dependencies và public methods.
|
||||
- Phân loại cái gì cần Mock (Services, 3rd Party APIs) và cái gì dùng Object thật (DTOs, Value Objects, Entities).
|
||||
- **Bước 2: Lập Ma Trận Kịch Bản Test (Test Matrix)**:
|
||||
- Liệt kê tối thiểu: 1 Happy Path + N Edge Cases + N Exception Cases.
|
||||
- **Bước 3: Lựa Chọn Template Tương Ứng**:
|
||||
- Liệt kê toàn bộ constructor dependencies và **TẤT CẢ các public methods**.
|
||||
- Phân tích chi tiết các rẽ nhánh logic: `if/else`, `??`, `?:`, `switch`, `match`, `try/catch`, `throw`.
|
||||
- Phân loại cái gì cần Mock (External Services, 3rd Party APIs) và cái gì dùng Object thật (DTOs, Value Objects, Entities).
|
||||
- **Bước 2: Lập Ma Trận Kịch Bản Đầy Đủ (Comprehensive Test Matrix)**:
|
||||
- Cho mỗi public method, liệt kê:
|
||||
+ 1+ Happy Path scenarios.
|
||||
+ N Edge Cases (null, empty, boundary numbers, unicode).
|
||||
+ N Branch scenarios (tất cả các nhánh điều kiện).
|
||||
+ N Exception/Failure scenarios (mock failure, validation error, database error).
|
||||
- **Bước 3: Lựa Chọn Template & Cú Pháp Chuẩn**:
|
||||
- CakePHP: Tham chiếu `templates/cakephp/phpunit/` và `docs/cakephp/`.
|
||||
- Laravel: Tham chiếu `templates/phpunit/`, `templates/pest/` và `docs/components/`.
|
||||
- **Bước 4: Sinh Mã Nguồn Test Hoàn Chỉnh**:
|
||||
- Đầy đủ Namespace, Use statements, Typed properties, strict assertions (`assertSame`).
|
||||
- Không viết code tắt, không dùng `// TODO`.
|
||||
- **Bước 4: Sinh Mã Nguồn Test Hoàn Chỉnh (Zero TODOs)**:
|
||||
- Đầy đủ Namespace, Use statements, Typed properties, Strict assertions (`assertSame`, `assertCount`).
|
||||
- Viết đầy đủ tất cả các test methods đã lập trong ma trận, không cắt ngắn.
|
||||
- **Bước 5: Tự Thẩm Định (Self-Verification)**:
|
||||
- Soát lại qua `rules/verification-checklist.md` trước khi xuất kết quả.
|
||||
- Đối chiếu mã nguồn vừa sinh qua `rules/verification-checklist.md` và `rules/edge-cases-matrix.md` trước khi xuất kết quả.
|
||||
|
||||
@@ -1,45 +1,57 @@
|
||||
# Checklist Tự Thẩm Định Chất Lượng Unit Test (Verification Checklist)
|
||||
|
||||
Trước khi xuất bất kỳ file test nào cho người dùng, Agent **BẮT BUỘC** phải tự đối chiếu mã nguồn của mình qua các câu hỏi kiểm định nghiêm ngặt dưới đây:
|
||||
Trước khi xuất bất kỳ file test nào cho người dùng, Agent **BẮT BUỘC** phải tự đối chiếu mã nguồn của mình qua các câu hỏi kiểm định nghiêm ngặt dưới đây để đảm bảo **TÍNH ĐẦY ĐỦ VÀ TOÀN DIỆN 100%**:
|
||||
|
||||
---
|
||||
|
||||
### [ ] 1. Tính Đơn Vị & An Toàn Cơ Sở Dữ Liệu (Isolation & DB Safety)
|
||||
### [ ] 1. Tính Đầy Đủ Của Phương Thức (Are ALL public methods tested?)
|
||||
- **100% public methods** của class nguồn đã có ít nhất một bộ test chưa?
|
||||
- Có bất kỳ helper method public, getter/setter có logic, formatters hoặc hook nào bị bỏ sót không?
|
||||
- Tuyệt đối không chỉ test hàm chính mà bỏ quên các hàm phụ còn lại trong class.
|
||||
|
||||
### [ ] 2. Độ Phủ Toàn Diện: Kịch Bản Biên, Ngoại Lệ & 100% Nhánh Rẽ (Edge Cases, Exceptions & All Branches)
|
||||
- **Happy Path**: Đã có test case với dữ liệu chuẩn xác chưa?
|
||||
- **Ngoại lệ (Exception)**: Đã có test case giả lập lỗi để ép mock ném Exception chưa?
|
||||
- **Khối try/catch**: Đã có test case kích hoạt và chạy qua toàn bộ thân khối `catch` chưa?
|
||||
- **Kịch bản biên**: Đã kiểm tra `null`, mảng rỗng `[]`, chuỗi rỗng `""`, chuỗi khoảng trắng `" "`, số `0`, số âm, giá trị cực đại chưa?
|
||||
- **Nhánh rẽ điều kiện**:
|
||||
- Mọi toán tử `??` và `?:` đã có test case cho cả 2 vế chưa?
|
||||
- Mọi toán tử logic `&&` và `||` đã kiểm thử đủ các tổ hợp điều kiện chưa?
|
||||
- Mọi nhánh `if`, `else if`, `else`, `switch`, `match` (kể cả nhánh `default`) đã được kích hoạt chưa?
|
||||
- Mọi Guard Clause và Early Return đã có test case kích hoạt chưa?
|
||||
|
||||
### [ ] 3. Kiểm Tra Trạng Thái & Tác Động Thực Tế (Are state mutations & side effects verified?)
|
||||
- Với Database: Đã kiểm tra bản ghi thật sự được tạo/sửa/xóa qua `assertDatabaseHas`, `assertDatabaseMissing` hoặc Fixture Table chưa?
|
||||
- Với Event/Queue/Mail: Đã assert Event được dispatch với đúng payload, Job được dispatch, Mail được gửi chưa?
|
||||
- Với Transaction: Đã test commit khi thành công và rollback khi thất bại chưa?
|
||||
|
||||
### [ ] 4. Tính Đơn Vị & An Toàn Cơ Sở Dữ Liệu (Isolation & DB Safety)
|
||||
- Test có đang vô tình gọi Database dev thật hoặc gọi router HTTP ngoài đời thực không?
|
||||
- Với **CakePHP**: Đã cấu hình dùng `Datasources.test` (SQLite `:memory:`) và khai báo Fixtures đầy đủ chưa?
|
||||
- Với **Laravel**: Đã cấu hình SQLite `:memory:` và mock các dịch vụ ngoài bằng Fake/Mockery chưa?
|
||||
|
||||
### [ ] 2. Cấu Trúc AAA Rõ Ràng (Is AAA clearly structured?)
|
||||
### [ ] 5. Cấu Trúc AAA Rõ Ràng (Is AAA clearly structured?)
|
||||
- Các khối `// Arrange`, `// Act`, `// Assert` có được phân định rõ ràng bằng comment không?
|
||||
- Khối `// Act` có đúng là chỉ thực hiện 1 hành động duy nhất không?
|
||||
|
||||
### [ ] 3. Mock Expectations Đầy Đủ (Are mock calls strictly verified?)
|
||||
### [ ] 6. Mock Expectations Chặt Chẽ (Are mock calls strictly verified?)
|
||||
- Mọi mock method có được khai báo số lần gọi cụ thể (`->once()`, `->never()`, `->times(N)`) thay vì bỏ trống không?
|
||||
- Các tham số truyền vào hàm mock có được kiểm tra qua `->with(...)` hoặc `->withArgs(...)` không?
|
||||
- Không over-mocking: DTO, Value Object, Collection, CakePHP Entity phải dùng instance thật.
|
||||
|
||||
### [ ] 4. Không Over-Mock DTO/Value Object/Entity (Are value objects kept real?)
|
||||
- Các đối tượng DTO, Value Object, Collection, CakePHP Entity có được tạo bằng instance thật thay vì mock không?
|
||||
|
||||
### [ ] 5. Độ Phủ Ngoại Lệ, Kịch Bản Biên & SonarQube Branches (Are edge cases & branches covered?)
|
||||
- Đã có test case cho trường hợp ném ngoại lệ (Exception) chưa?
|
||||
- Đã kiểm tra các trường hợp biên: `null`, mảng rỗng `[]`, số `0`, số âm chưa?
|
||||
- Mọi toán tử `??` và `?:` đã có test case cho cả 2 vế chưa?
|
||||
- Mọi khối `try/catch` đã có test case ép mock ném Exception để chạy qua khối `catch` chưa?
|
||||
|
||||
### [ ] 6. Không Bỏ Sót Phương Thức & Trait Cốt Lõi (Are all core methods & traits tested?)
|
||||
### [ ] 7. Quy Chuẩn Thành Phần Riêng Biệt (Are component-specific conventions followed?)
|
||||
- **CakePHP Controller**: Đã sử dụng `Cake\TestSuite\IntegrationTestTrait` và gọi `$this->enableCsrfToken()`, `$this->enableSecurityToken()` khi test POST/PUT chưa?
|
||||
- **CakePHP Command**: Đã sử dụng `Cake\Console\TestSuite\ConsoleIntegrationTestTrait` và assert exit code (`assertExitSuccess()`) chưa?
|
||||
- **CakePHP Mailer**: Đã sử dụng `Cake\TestSuite\EmailTrait` chưa?
|
||||
- **Laravel Job hoặc Command**: Đã test phương thức **`handle()`** và `failed()` chưa? Tuyệt đối không chỉ test helper phụ!
|
||||
- Tất cả các `public methods` của class đã có ít nhất một bài test tương ứng chưa?
|
||||
- **CakePHP Table**: Đã test `validationDefault()` cho từng rule, `buildRules()`, custom finders và save/delete chưa?
|
||||
- **Laravel Job**: Đã test cả phương thức **`handle()`** và **`failed(Throwable $e)`** chưa?
|
||||
- **Laravel Repository**: Đã test query thật trên SQLite in-memory chưa (cấm chỉ assert `Builder::class`)?
|
||||
- **Laravel FormRequest**: Đã test `authorize()` (true & false) và test từng rule vi phạm riêng biệt chưa?
|
||||
- **Laravel Policy**: Đã test mọi action cho cả user có quyền (true) và không có quyền (false) chưa?
|
||||
|
||||
### [ ] 7. Assertions Chặt Chẽ & Có Nghĩa (Are assertions meaningful?)
|
||||
### [ ] 8. Assertions Chặt Chẽ & Có Nghĩa (Are assertions meaningful?)
|
||||
- Có sử dụng Strict Assertion (`assertSame`, `toBe`) thay vì loose assertion không?
|
||||
- Với CakePHP: Có dùng assertion chuyên dụng (`assertResponseOk()`, `assertRedirect()`, `assertFlashMessage()`) không?
|
||||
- Có bị dính assertion rỗng kiểu `$this->assertTrue(true)` không?
|
||||
|
||||
### [ ] 8. Đặt Tên Chuẩn & Dễ Đọc (Are method names expressive?)
|
||||
- Tên test method có thể hiện rõ "Hành động + Kết quả + Ngữ cảnh" không? (Ví dụ: `testValidationFailsWhenTitleIsEmpty` hoặc `testAddPostSuccessWithAuth`)
|
||||
- Tuyệt đối KHÔNG có assertion rỗng kiểu `$this->assertTrue(true)` hay `// TODO`.
|
||||
|
||||
### [ ] 9. Cú Pháp Đúng Phiên Bản Framework (Is syntax version-accurate?)
|
||||
- Nếu là PHPUnit 10+: Đã dùng Attribute `#[Test]` và `#[DataProvider]` thay cho DocBlock cũ chưa?
|
||||
|
||||
Reference in New Issue
Block a user