8f7212ef65
- Add sonar-project.properties templates for CakePHP and Laravel - Update install.sh to automatically provision SonarQube config - Enhance cakephp-unit-test skill with exhaustive branch coverage rules - Update SonarQube guide with CakePHP specific rules and exclusion patterns - Enhance TableTest template with buildRules and validation failure cases
157 lines
8.4 KiB
Markdown
157 lines
8.4 KiB
Markdown
---
|
|
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 100% từng nhánh SonarQube, 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 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ó 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/empty).
|
|
- **Toán tử `?:` (Ternary)**: Bắt buộc 2 test case (true & false).
|
|
- **Toán tử 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`**: 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 Để Đạt > 90%**:
|
|
- **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
|
|
```
|