--- name: cakephp-unit-test description: Phân tích một class mã nguồn PHP CakePHP (Table, Entity, Controller, Service, Command, Component, Middleware, Mailer, Form, Behavior) và tự động sinh file Unit / Integration Test hoàn chỉnh đạt chuẩn AAA, cô lập cao và bao phủ biên. --- # Skill: CakePHP Unit & Integration Test Generator Skill này là công cụ chính để tự động tạo ra file Test cho bất kỳ class nào trong dự án CakePHP (từ CakePHP 3.x, 4.x đến 5.x+). ## Cách kích hoạt ### 🏆 QUY TRÌNH CHUẨN PRO CHO DỰ ÁN LỚN (KHUYÊN DÙNG NHẤT): Để tránh bị tràn context token và đảm bảo viết sâu, đầy đủ 100% từng logic và nhánh rẽ, hãy tách biệt 2 pha: **PHA VIẾT (Generation)** và **PHA CHẠY (Execution)**: 1. **Bước 1: Quét bản đồ dự án (`--untested`)**: ```text /cakephp-unit-test --untested ``` *Liệt kê danh sách class trong `src/` chưa có test trong `tests/TestCase/` theo độ ưu tiên: Tables/Entities -> Services -> Controllers -> Commands -> Components/Middlewares.* 2. **Bước 2: Viết test tập trung theo từng tầng (CHỈ VIẾT, CHƯA CHẠY TEST)**: ```text /cakephp-unit-test src/Model/Table/ # Sau khi xong, viết tiếp: /cakephp-unit-test src/Service/ /cakephp-unit-test src/Controller/ /cakephp-unit-test src/Command/ ``` *AI dồn 100% token tập trung sinh test sâu, đầy đủ Happy Path, Edge Cases, Exception và Branch Coverage.* 3. **Bước 3: Chạy test đồng loạt ngoài Terminal & Nghiệm thu**: ```bash ./test-runner.sh --coverage ``` *Chạy 1 lần duy nhất bằng `bin/cake test app` hoặc `phpunit` trên In-memory SQLite siêu tốc, đo độ phủ và xuất file báo cáo.* --- ### ⚡ CÁC CHẾ ĐỘ TIỆN ÍCH KHÁC: 4. **Chế độ Autopilot Khép Kín: Viết & Chạy Test Ngay (`--all --run` hoặc `--autopilot`)**: ```text /cakephp-unit-test --all --run ``` *Dành cho dự án vừa và nhỏ: AI tự lập manifest, viết đến đâu chạy `./test-runner.sh` ngay đến đó, tự động sửa lỗi (Auto-Healing) nếu test fail.* 5. **Chế độ Viết Cho 1 File & Test Luôn (`--run`)**: ```text /cakephp-unit-test src/Model/Table/UsersTable.php --run ``` 6. **Chế độ Theo Git Diff (Dành Cho Pull Request)**: ```text /cakephp-unit-test --changed ``` 7. **Chế độ File đơn lẻ**: ```text /cakephp-unit-test src/Controller/ArticlesController.php ``` --- ## Quy trình 6 Bước Tự Động của Agent ### Bước 1: Khảo sát Môi trường & Phiên bản CakePHP 1. Đọc `composer.json` để xác định: - **Phiên bản CakePHP**: - CakePHP 5.x: PHP >= 8.1, kiểu khai báo kiểu nghiêm ngặt (strict types), Attributes PHP 8 `#[Test]`. - CakePHP 4.x: PHP 7.4 - 8.2, `Cake\TestSuite\TestCase`, dùng `fetchTable()`. - CakePHP 3.x: `TableRegistry::get()`. - **PHPUnit**: PHPUnit 9 / 10 / 11. ### Bước 2: Phân tích File Nguồn & Xác Định Loại Component 1. Đọc toàn bộ nội dung file class nguồn được chỉ định. 2. Xác định cấu trúc Component CakePHP: - **Table (`src/Model/Table/*Table.php`)**: Test validation rules, custom finder methods (`findTagged()`, `findAuth()`), buildRules, save/delete logic. - **Entity (`src/Model/Entity/*.php`)**: Test virtual fields, mutators (`_setPassword()`), accessors, hidden/accessible properties. - **Controller (`src/Controller/*Controller.php`)**: Dùng `Cake\TestSuite\IntegrationTestTrait`. Test endpoints HTTP (GET, POST, PUT, DELETE), flash messages, redirect, view vars, auth/session. - **Service / Action (`src/Service/*.php`)**: Test logic nghiệp vụ thuần túy, mock các dependency ngoài hoặc Table locator. - **Command (`src/Command/*Command.php`)**: Dùng `Cake\Console\TestSuite\ConsoleIntegrationTestTrait`. Test arguments, options, output text, exit code (`CODE_SUCCESS`, `CODE_ERROR`). - **Component (`src/Controller/Component/*.php`)**: Test logic tái sử dụng của Controller với mocked Controller/Request/Response. - **Middleware (`src/Middleware/*.php`)**: Test PSR-15 / CakePHP middleware với `ServerRequest` và `ResponseHandler`. - **Mailer (`src/Mailer/*Mailer.php`)**: Dùng `Cake\TestSuite\EmailTrait`. Test subject, to, template, view vars. - **Form (`src/Form/*Form.php`)**: Test `validationDefault()`, `_buildSchema()`, `_execute()`. - **Behavior (`src/Model/Behavior/*.php`)**: Test ORM hooks (`beforeSave`, `beforeFind`,...). - **Helper (`src/View/Helper/*.php`)**: Test render HTML, tags, view outputs. ### Bước 3: Xác Định Fixtures & Chiến Lược Giả Lập (Mocking) - **Database & Fixtures**: - Đối với Table & Controller test: Xác định các bảng liên quan để khai báo fixture: ```php protected array $fixtures = [ 'app.Users', 'app.Articles', ]; ``` - **External Dependencies & APIs**: - Dùng Mockery hoặc PHPUnit Mock (`$this->createMock()`) cho các HTTP Client ngoài, 3rd party SDKs, Payment Gateway. - **Session & Auth**: - Đối với Controller: `$this->session(['Auth.User.id' => 1])` hoặc Token-based Auth. - Kích hoạt CSRF & Security token khi test POST: ```php $this->enableCsrfToken(); $this->enableSecurityToken(); ``` ### Bước 4: Lập Ma Trận Test Scenarios (Đảm Bảo Viết Test Đầy Đủ & Toàn Diện 100%) Mục tiêu cốt lõi: Viết bộ test hoàn chỉnh nhất, bao phủ cả Line Coverage và Branch Coverage mà không bỏ sót bất kỳ phương thức hay kịch bản nào. 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ó test cases đầy đủ. 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/empty). - **Toán tử `?:` (Ternary)**: Bắt buộc 2 test case (true & false). - **Toán tử logic `&&` và `||`**: Phải test toàn bộ các kịch bản kết hợp để thỏa mãn mọi điều kiện rẽ nhánh. - **Khối `try - catch`**: BẮT BUỘC có test case ép mock/dữ liệu 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 Thành Phần CakePHP Để Bao Phủ Đầy Đủ**: - **ORM Table (`validationDefault`)**: Bắt buộc test dữ liệu hợp lệ VÀ các trường hợp vi phạm cho **từng rule**: - Thiếu trường (`requirePresence`) - Chuỗi rỗng (`notEmptyString`) - Quá độ dài (`maxLength`) - Sai định dạng (`email`, `integer`, `url`, số âm). - **ORM Table (`buildRules`)**: Test cả 2 trường hợp: rule hợp lệ và rule bị vi phạm (`isUnique`, `existsIn`). - **Controller (IntegrationTestTrait)**: - GET request: Render view thành công (200). - POST/PUT save thành công: Redirect 302 + Flash Success. - POST/PUT save thất bại: Render view 200 + Flash Error. - Unauthorized / Unauthenticated: Redirect login (hoặc 403). - Not Found: Bắt RecordNotFoundException (404). - **Console Command (ConsoleIntegrationTestTrait)**: - Test chạy thành công: `assertExitSuccess()`. - Test chạy lỗi hoặc thiếu options: `assertExitError()`. - Test stdout chứa thông báo mong đợi: `assertOutputContains()`. ### Bước 5: Sinh Mã Nguồn Test Chuẩn Mirror 1. Xác định đường dẫn file test theo chuẩn CakePHP: - Nguồn: `src/Model/Table/ArticlesTable.php` - Đích: `tests/TestCase/Model/Table/ArticlesTableTest.php` - Nguồn: `src/Controller/ArticlesController.php` - Đích: `tests/TestCase/Controller/ArticlesControllerTest.php` - Nguồn: `src/Command/CleanCacheCommand.php` - Đích: `tests/TestCase/Command/CleanCacheCommandTest.php` 2. Sử dụng đúng base class: - `Cake\TestSuite\TestCase` (kèm các Trait tương ứng: `IntegrationTestTrait`, `ConsoleIntegrationTestTrait`, `EmailTrait`). 3. Viết code theo mô hình **AAA** (`// Arrange`, `// Act`, `// Assert`). ### Bước 6: Thẩm định & Lưu File 1. Tự kiểm tra file test qua checklist quy chuẩn. 2. Ghi file test vào thư mục `tests/TestCase/...`. 3. In ra lệnh chạy test gợi ý: ```bash bin/cake test app tests/TestCase/Model/Table/ArticlesTableTest.php # Hoặc: ./test-runner.sh --filter=ArticlesTableTest ```